Linux 网络排查命令速查:连接数暴涨到 2 万那晚,我是这样用 ss、tcpdump、mtr、dig 一层层揪出真凶的

📅 2026/7/31 18:04:41
Linux 网络排查命令速查:连接数暴涨到 2 万那晚,我是这样用 ss、tcpdump、mtr、dig 一层层揪出真凶的
摘要服务器突然抽风、502、新连接建不出网络排查工具一大堆却不知先敲哪条本文按「连通性 → 端口连接 → DNS → 抓包 → 网卡流量」分层速查 ss、tcpdump、mtr、dig、lsof、nc、ip 等核心命令重点讲 ss 怎么按状态数连接并复盘一次 TCP 连接从 5k 暴涨到 2 万的实战顺带拆穿 TIME_WAIT、CLOSE_WAIT、%util 三个经典误解。半夜告警炸群支付超时、登录转圈、接口抽风式 502。你 SSH 上机器top看着不高日志翻不出堆栈这时候——你第一条命令敲什么大多数人卡就卡在这网络排查的命令一抓一大把ping、netstat、tcpdump、ss、dig……但手忙脚乱地乱敲和按层次一条链路查下去是两种完全不同的体验。这篇把这套工具按「排查顺序」串成一份速查表最后用一次真实的连接数暴涨事故演示怎么从现象一路查到根因。一、先建立一张分层排查地图网络问题几乎都能套进 TCP/IP 的分层模型里排查。与其记一堆命令不如先记住从下往上、从近到远这条主线每一层配一两个趁手的命令排查层次你在问什么主力命令① 本机网卡 / 路由网卡起来没路由对不对ip a/ip r/ethtool② 连通性 / 路径能不能到对端中间哪一跳丢包ping/traceroute/mtr③ 端口 / 连接端口通不通连接堆在什么状态ss/lsof/nc④ DNS域名解析对不对解析到哪去了dig/nslookup/host⑤ 报文真相到底收发了什么谁先 RST 的tcpdump⑥ 流量带宽被谁吃满了iftop/nload/iptraf-ng 这张表是分层地图用来快速定位问题落在哪一层但后文的讲解顺序按实战命中率来——线上问题十有八九落在「连接层」所以下面从最常用的ss讲起而不是死板地从网卡往上铺。真正上手排查时仍记住一点先证伪最底层网卡、连通性再往上查应用层能避免一上来就tcpdump抓一堆看不懂的包。本文默认你已经会用curl做 HTTP 层的探测和计时——那块是另一个大主题这里不展开详见 《curl 实战程序员必备的接口调试与性能排查利器》。二、端口与连接ss 才是主角netstat 该退休了排查线上问题十次有八次落到「连接」这一层——端口通不通、连接堆在什么状态、谁占满了连接池。这层的主角是ss不是很多人肌肉记忆里的netstat。2.1 为什么用 ss 不用 netstat维度netstatnet-toolsssiproute2数据来源逐行解析/proc/net/*走 netlink 的sock_diag接口几万连接时慢到能泡杯茶逐行读 /proc快一个数量级维护状态net-tools 早已停更、多数发行版默认不装iproute2 官方在维护状态过滤只能grep原生state/sport/dport表达式结论netstat只在老机器上应急新机器一律ss。连接一多的时候netstat自己都可能卡住ss才是你要的。2.2 ss 速查# 一眼看全局:各类 socket 总数 TCP 各状态计数(排查连接暴涨第一条)ss-s# 列 TCP 连接:-t TCP / -u UDP / -a 全部 / -n 不解析端口名 / -p 显示进程ss-tanp# 只看监听端口(服务起没起、监听在哪个地址)ss-tlnp# 按状态过滤:只看 TIME-WAIT / ESTABLISHED / CLOSE-WAITss-tanstate time-wait ss-tanstate established ss-tanstate close-wait# 按端口过滤:连到 8123(比如某个数据库)的所有连接ss-tanp( dport :8123 or sport :8123 )# 按对端 IP 过滤ss-tanpdst10.0.1.5# 王牌一条:按状态给连接分组计数(定位「连接堆在哪个状态」)ss-tan|awkNR1 {print $1}|sort|uniq-c|sort-rn# 数某个状态有多少条(记得减掉表头)ss-tanstate time-wait|wc-lss -s的输出长这样示意Total: 22185 TCP: 22037 (estab 812, closed 20800, orphaned 3, timewait 20790)一眼就能读出关键信息总连接 22037其中timewait 就占了 20790——这是个强烈的信号后面第八节会拿它当破案线索。2.3 看懂 TCP 状态TIME_WAIT 和 CLOSE_WAIT 到底谁的锅ss输出里的状态列是排查的核心。两个最容易堆积、也最容易背锅的状态一定要分清状态含义大量堆积说明什么ESTAB连接正常建立、正在用正常异常高要结合业务看是不是连接泄漏TIME-WAIT主动关闭方发完最后一个 ACK 后的等待期通常是你这端在疯狂主动断连短连接高频多数无害CLOSE-WAIT对端已关本端应用迟迟没close()⚠️应用 Bug代码没关连接 / 连接泄漏越堆越多迟早耗尽 fdSYN-SENT发了 SYN 等对端回大量堆积 连不上对端对端挂了 / 防火墙 / 端口没开SYN-RECV收到 SYN 回了 SYN-ACK 等 ACK大量堆积 可能被 SYN flood或对端回不来一句话记忆TIME-WAIT 是你太勤快地关连接CLOSE-WAIT 是你忘了关连接。前者调参数后者改代码。TCP 十一种状态的完整状态机源自 RFC 793排查时不用背全但ESTAB / TIME-WAIT / CLOSE-WAIT / SYN-*这几个高频状态的含义必须张口就来。三、连通性与丢包ping、traceroute、mtr端口层之外第二高频的是「到底通不通、在哪丢包」。# 基础连通性(-c 次数,别忘了很多云主机默认禁 ICMP,ping 不通不等于服务不通)ping-c4example.com# 路径追踪:看数据包经过哪些跳、哪一跳开始变慢tracerouteexample.com# mtr ping traceroute 合体,持续统计每一跳的丢包率和延迟(排跨网/跨境问题神器)mtr-rwzbc100example.com# -r 报告模式 / -w 宽输出 / -z 显示 ASN / -b 同时显示 IP 和域名 / -c 100 探测 100 次mtr的杀手锏是分段定位丢包如果丢包从第 6 跳才开始、且一路持续到目的地那问题大概率在第 6 跳那个运营商节点而不是你的机器或对端服务。⚠️中间跳丢包不一定是真丢包很多路由器对 TTL 耗尽的 ICMP 限速deprioritize会显示某一跳丢包但末跳正常——只有末跳持续丢包才是真丢包中间跳单独丢包往往是幻觉。跨境上传慢、大文件传输卡这类看着像后端锅、实为链路丢包的实战可参考 《上传 20MB 视频花了 11 分钟真凶不是 Nginx也不是后端是跨境丢包》。四、DNSdig、nslookup、host“代码没动、就是连不上”十次里有几次是 DNS 解析出了岔子解析超时、解析到旧 IP、解析到内网/外网错了地址。# 最常用:只要解析结果,干净利落digshort example.com# 指定 DNS 服务器查(排查是不是本机 DNS 缓存/配置的问题)digexample.com 1.1.1.1# 只看 answer 段,别的噪音都去掉digexample.com A noall answer# 从根域一路追下来,看解析链路在哪断(排查解析不一致)digtrace example.com# 反向解析:IP 查域名dig-x10.0.1.5# 轻量版(nslookup 更老但到处都有;host 输出最简洁)nslookupexample.comhostexample.com排查套路先dig short看解析结果对不对不对再dig 公共DNS对比——如果换个 DNS 就正常那是本机/etc/resolv.conf或内网 DNS 的问题如果换谁都错那是权威记录本身配错了。域名明明能解析、curl也通就是浏览器打不开那可能是代理/fake-ip层的坑和 DNS 解析本身无关排查思路见 【待发布后补充引用关系《curl 通、关掉代理也通就浏览器打不开一次 Clash TUN fake-ip 的三层排查》】。五、端口探测与占用nc、telnet、lsof# 探端口通不通(-z 只探测不发数据 / -v 详细 / -w 2 超时 2 秒)nc-zv-w210.0.1.58123# 老古董但哪都有:telnet10.0.1.58123# 谁占了这个端口?(排查端口已被占用 / Address already in use)lsof-i:8123 ss-tlnp( sport :8123 )# ss 也能干同样的活# 某个进程开了哪些网络连接lsof-i-nP-pPID# 本机所有 ESTABLISHED 连接 对应进程lsof-i-nP|grepESTABLISHEDnc -zv host port是验证端口层通不通最快的一条命令——比起curl还要发 HTTP 请求nc只做 TCP 握手能干净地把「网络不通」和「应用层报错」区分开。六、抓包tcpdump 最小必备姿势前面几层都定位不了就得看报文真相了到底谁先发的 RST握手卡在哪一步# 抓指定主机端口,-nn 不解析 IP 和端口名(否则反向解析能卡死你)tcpdump-iany-nn-c20host10.0.1.5 and port8123# 存成 pcap 拖回本地用 Wireshark 慢慢看(线上抓包首选,别在终端直接肉眼看)tcpdump-iany-nnhost10.0.1.5 and port8123-w/tmp/cap.pcap# 看内容(-A 以 ASCII 打印,排查明文协议;-X 十六进制ASCII)tcpdump-iany-nn-Ahost10.0.1.5 and port80# 只抓 SYN 包(排查握手建不起来 / 谁在发起连接)tcpdump-iany-nntcp[tcpflags] tcp-syn ! 0# 只抓 RST 包(排查连接被谁重置了)tcpdump-iany-nntcp[tcpflags] tcp-rst ! 0三条铁律一定加-nn不解析主机名和端口名否则 tcpdump 每抓一个包都去做一次反向 DNS现场直接卡住。线上优先-w存文件别在终端裸看抓下来用 Wireshark 分析过滤和追踪流Follow TCP Stream方便一万倍。过滤条件写精准host x and port y不然高流量机器上瞬间几十万个包信息全淹了。七、网卡、路由与流量ip、ethtool、iftop最底层的物理排查以及带宽被谁吃了。# 网卡地址 / 路由 / ARP 邻居(ip 已全面取代 ifconfig、route、arp)ip-bra# 简洁版,一行一个网卡ipr# 路由表ipneigh# ARP 邻居表ip-slink# 收发包统计,看 errors/dropped# 网卡协商速率 / 双工 / 链路状态(排查网卡跑在 100M 没跑到千兆)ethtooleth0# 网卡级错误统计:丢包、CRC 错误、ring buffer 溢出ethtool-Seth0|grep-Eierr|drop|discard# 实时看谁在吃带宽(按连接维度)iftop-ieth0# 按网卡看总进出带宽nload# 综合流量监控iptraf-ngip -s link里的errors/dropped和ethtool -S里的 drop 计数是排查偶发丢包、莫名重传时容易被忽略的一层——网卡 ring buffer 溢出、协商速率不对应用层是完全无感的。容器里没有这些命令怎么办容器镜像往往精简掉了ss/tcpdump。不用往容器里装直接在宿主机上钻进容器的网络命名空间执行PID$(dockerinspect-f{{.State.Pid}}容器名)nsenter-t$PID-nss-tanp# 用宿主机的 ss 看容器的连接nsenter-t$PID-ntcpdump-nn-iany八、实战连接数从 5k 冲到 2 万ss 一条链路揪出真凶光有速查表不够来看一次真实事故怎么用这套工具串起来破案细节已脱敏。现象一个 C 端在线服务OLTP 主接口间断性 502、抽风式不可用。top看 CPU 不算高进程也没挂但新请求就是进不来。第一步——先看连接层ss -sTCP: 22037 (estab 812, closed 20800, orphaned 3, timewait 20790)平时这台机器 TCP 连接常态几千现在冲到2.2 万而且一眼就看出结构不对estab才 812timewait却有 2 万。连接被大量快速地建立又关闭——这不是正常业务流量该有的形状。第二步——按状态分组确认ss分组计数ss-tan|awkNR1 {print $1}|sort|uniq-c|sort-rn# 20790 TIME-WAIT# 812 ESTAB# 3 SYN-SENTTIME-WAIT 独大说明是本机在疯狂主动关连接。谁在关第三步——按端口定位是谁ss端口过滤ss-tanp( dport :8123 )|head一过滤发现海量连接指向下游某个8123端口的服务一个 OLAP 数据库。再顺着进程一看是应用的健康检查在每秒几百次地去 ping 这个下游依赖每次都新建连接、用完就关——于是 TIME-WAIT 像滚雪球一样堆到 2 万把本机指向下游的 ephemeral 端口和连接资源逼近上限叠加下游查询本身已经 hang 住应用既拿不到可用连接、也建不出新的出站连接对外表现就是抽风式 502。第四步——旁证tcpdump/ 监控抓包确认这些连接都是短命的建连→关连和 grafana 上的TCP_alloc、TCP_tw曲线暴涨完全对上。根因下游数据库磁盘写满导致查询 hang、连接被占满最终锁定。① ss -sTCP 2.2万·timewait 2万结构异常② ss 分组计数TIME-WAIT 独大本机在疯狂关连接③ ss 端口过滤dport:8123海量连向下游 OLAP④ tcpdump 监控短命建连关连TCP_tw 曲线对上·锁定根因这条链路的价值在于ss -s一眼看出连接结构异常 → 分组计数确认状态 → 端口过滤锁定下游 → 抓包/监控闭环。从现象到嫌疑人ss 一个工具就走完了大半。这次事故的完整复盘OLAP 数据库混进 OLTP 主链路、健康检查打爆连接池的连锁反应见 《OLAP 数据库混进 OLTP 链路一次 ClickHouse 拖死 API 101 分钟的复盘》。九、踩坑记录那些年我们误解的网络命令坑 1以为tcp_fin_timeout能调短 TIME-WAIT经典误区。Linux 上TIME-WAIT 的时长是内核里写死的 60 秒TCP_TIMEWAIT_LENnet.ipv4.tcp_fin_timeout调的是FIN-WAIT-2状态不是 TIME-WAIT。想缓解 TIME-WAIT 堆积方向是net.ipv4.tcp_tw_reuse仅对主动发起的出站连接安全。⚠️ 另一个参数tcp_tw_recycle千万别开——它在 NAT 环境下会导致丢包而且已在内核 4.12 中被移除。这段的权威解释见 Vincent Bernat 的 《Coping with the TCP TIME-WAIT state on busy Linux servers》把 TIME-WAIT 的成本和调优讲得最透。参数语义可查man 7 tcp。坑 2把 CLOSE-WAIT 堆积也当成调参数的问题CLOSE-WAIT 堆积100% 是应用的锅——对端已经关了连接你的代码却没调用close()。调任何内核参数都没用得去查代码数据库连接、HTTP client、文件句柄是不是没在finally里关。CLOSE-WAIT 只增不减就是连接/句柄泄漏的铁证。坑 3%util100% 就以为磁盘/网卡到顶了虽然这条是 IO 侧的老梗但网络排查里同样适用一个思维%util是繁忙时间占比而非利用率。单队列设备哪怕只有一个请求在飞只要它一直在飞%util就能显示 100%但设备其实很闲。看到 100% 别急着下到顶了的结论用队列深度、await这些指标交叉验证。坑 4ping不通就断定网络不通大量云主机、安全组默认禁 ICMP。ping不通完全可能只是 ICMP 被墙而 TCP 端口好好的。判断端口层通不通要用nc -zv host port或curl别拿ping当唯一依据。坑 5tcpdump不加-nn现场被自己卡死不加-nntcpdump 会对每个包的 IP 做反向 DNS、对端口查/etc/services高流量下光解析就能把命令拖到不动还额外制造 DNS 流量污染现场。线上抓包-nn是肌肉记忆。十、场景 → 命令速查表排查时按现象直接查命令不用从头想现象 / 场景先敲这条再敲这条服务抽风、新连接建不出ss -sss -tan | awk NR1{print $1} | sort | uniq -c连接池/句柄疑似泄漏ss -tan state close-wait | wc -llsof -i -nP -p PID端口通不通nc -zv -w2 host portss -tlnp对端看监听跨网/跨境时快时慢mtr -rwzbc 100 hosttcpdump -w抓包看重传域名解析异常dig short 域名dig 域名 1.1.1.1对比连接被莫名重置tcpdump -nn tcp[tcpflags] tcp-rst!0看谁先发的 RST带宽被吃满iftop -i eth0nload偶发丢包/重传ip -s linkethtool -S eth0 | grep -i drop容器内排查nsenter -t PID -n ss -tanpnsenter -t PID -n tcpdump十一、总结网络排查的关键不在于记住多少命令而在于建立分层、从下往上的顺序感让每个工具各就各位连接层用ss告别netstatss -s看全局、分组计数看状态、端口过滤锁嫌疑这一套能解掉大半线上连接类问题连通性用mtr比 ping/traceroute 更能定位丢包记住只有末跳持续丢包才是真丢DNS 用dig short/dig 公共DNS对比快速区分本机配置还是权威记录的问题报文真相用tcpdump -w抓下来给 Wireshark-nn别忘状态含义分清TIME-WAIT 是关太勤调参数CLOSE-WAIT 是忘了关改代码。把这份速查表存起来下次半夜告警时你敲的第一条命令就不再是top之后的一片茫然而是ss -s。延伸阅读《curl 实战程序员必备的接口调试与性能排查利器》 —— HTTP 层的探测与计时和本文互补《上传 20MB 视频花了 11 分钟真凶不是 Nginx也不是后端是跨境丢包》 ——mtr定位丢包的实战【待发布后补充引用关系《curl 通、关掉代理也通就浏览器打不开一次 Clash TUN fake-ip 的三层排查》】 —— DNS / 代理层的排查《AI 服务 502 雪崩排查从 Nginx 超时到连接池耗尽查了两次才找到真凶》 —— 连接池耗尽的另一种姿势权威参考man 8 ss、man 7 tcp、tcpdump 官方 man、Vincent Bernat: Coping with TCP TIME-WAIT️ 标签Linux网络排障sstcpdumpTCP运维实战