Linux 网络排查实战手册:分层思路与常用工具详解 📅 发布时间:2026/9/16 1:26:50 👁 浏览次数: 排查 Linux 网络问题我见过太多同事在生产环境里瞎忙活。登录服务器先ping一下网关通了就不知道下一步干啥了业务方反馈访问慢他盯着top看半天 CPU完全没意识到是网络层出了鬼。说白了不是不会用命令是没有一套成体系的网络调试思路不知道什么场景该上什么工具更不知道输出结果怎么解读。这篇文章我从实际运维和故障排查的角度把 Linux 网络 Debug 最常用的工具串一遍。从最基础的连通性验证到链路质量监控、TCP 连接状态分析、DNS 解析排查、数据包级抓包再到带宽压测和实时流量观察每一类都讲清楚适用场景、核心参数和典型的踩坑记录。看完你至少能在下次网络故障时按图索骥快速定位问题在哪一层。1. 网络 Debug 的思路先分层再定位网络排查最怕没有章法。我自己的习惯是严格按照 TCP/IP 分层模型来排查从物理层往应用层一层层做排除。1.1 别急着抓包先确定问题出在哪一层很多人一上来就tcpdump结果抓到一堆包不知道看哪个。正确做法是先从高层往下层走或者从低层往上走看哪一层断了。我常用的分层排查思路是这样的应用层先确认服务本身有没有起端口有没有监听。用ss -lntp看监听状态用curl试一下本地回环能不能通。传输层确认端口连通性。telnet或nc指定端口连一下看 TCP 握手能不能完成。网络层确认路由可达。ping网关、ping对端 IP看基本连通性traceroute看中间经过哪些节点。链路层/物理层ethtool看网卡状态、速率、丢包统计ip -s link看接口收发包的错误计数。打个比方这就像排查家里水管漏水。你得先确定是主管道漏网络层断了还是水龙头坏了应用层没监听而不是先把墙砸了。分层排查的精髓就是每层都有对应的工具每层工具的定位结果决定了你下一步该往哪个方向走。1.2 一个真实案例业务方说连不上数据库我曾经处理过一起典型的连不上数据库事件。业务方反馈应用报错说连不上 MySQL。我先telnet了 MySQL 的 3306 端口通了再用mysql -h从本地客户端连也正常。这就说明网络层和传输层没问题问题大概率出在应用层——可能是业务方的连接池配置错了或者是账号权限问题。反过来如果telnet3306 端口不通我再回到ping数据库服务器的 IP如果 ping 通了但端口不通重点关注的是防火墙策略iptables/firewalld或者 MySQL 的bind-address配置只监听了内网 IP。找准层级排查效率就高很多。2. 连通性与链路质量排查ping、telnet 与 nc这一节先讲最基础的连通性工具。别看命令简单细节非常多很多老手也未必注意到了。2.1 最熟悉的ping不一定是最熟悉的用法ping用的是 ICMP Echo 报文我最常用来做三类判断本机网络栈是否正常、网关是否可达、远端主机是否存活。但是有几个点特别容易忽略ping不通不等于网络不通。很多云环境或服务器的安全组、防火墙策略会丢弃 ICMP 报文。生产环境里我遇到过好几次业务 TCP 端口完全正常但ping就是不通最后发现是安全组只放行了 TCP 端口ICMP 被默认丢弃。所以正确做法是ping不通时立刻用telnet IP 端口或nc -vz IP 端口验证 TCP 层别在 ICMP 上死磕。再说ping的参数。日常排查我一般用ping -c 4 -W 2 target-c指定发送次数-W指定超时秒数。如果要做持续性的丢包率监控我会用ping -i 0.2 -c 1000 target把间隔调到 0.2 秒刷 1000 个包统计丢包率和延迟分布。ping输出的核心看三点time值代表往返延迟packet loss代表丢包率min/avg/max代表延迟抖动范围。如果time忽高忽低比如从 0.5ms 跳到 200ms那说明链路有拥塞或路由有问题。2.2telnet和nc端口连通性的黄金搭档telnet IP port是最直接的端口探测方式。连上了就说明 TCP 三次握手成功连不上会有几种报错Connection refused说明对端主机在线但这个端口没有服务在监听。通常是服务没启动或者监听的地址不对比如只监听了 127.0.0.1外部访问肯定会被拒绝。Connection timed out说明包发出去没回应。可能是对端防火墙丢包也可能是中间路由不可达需要配合traceroute判断。ncnetcat比 telnet 更灵活。nc -vz -w 3 target port是静默探测模式-v显示详情-z只扫描不发送数据-w 3指定超时。我特别喜欢用它做端口范围扫描比如要确认某台服务器开放了哪些端口nc -vz -w 1 192.168.1.100 1-1000 21 | grep succeeded这行命令会把 1 到 1000 端口扫一遍只显示开放的端口。实际工作中我也常用nc来测试 UDP 端口nc -uvz target port不过 UDP 的通和不通很难界定因为 UDP 本身没有握手确认超时并不一定代表端口不通这个要特别留意。2.3 链路质量探测traceroute和mtrping只能告诉你通不通和延迟多少但如果路由中间有某个节点出问题你没法直接看出来。这时候要用traceroute。traceroute的原理是利用 TTLTime To Live逐跳递减每经过一个路由器 TTL 减 1减到 0 时路由器会返回 ICMP Time Exceeded 报文。这样就能把路径上的每一跳都摸出来。我常用的参数traceroute -n -T -p 443 target-n不做反向 DNS 解析省时间也不容易卡住-T用 TCP SYN 探测很多网络会把 ICMP 丢弃但 TCP 是放行的-p 443指定探测端口。mtr是更强大的版本它结合了ping和traceroute的功能持续探测每一跳的丢包率和延迟。我的习惯是mtr -rwz -c 100 target-r是 report 模式跑完打印结果直接退出-w显示宽格式-z显示 AS 号对判断跨运营商链路问题很有帮助。mtr输出里面有个核心判断点如果最后一跳的丢包率高但前面几跳都是 0%不用太担心很多节点对 ICMP 限速会故意丢包如果中间某一条从 3 跳到 10 跳都持续丢包那才是真正的链路问题需要联系运营商或调整路由。3. TCP 连接状态与端口状态排查ss 与 netstat这是排查连接数爆了端口被占TIME_WAIT 堆积等问题的核心工具区。3.1 别再依赖netstat了ss才是现代首选很多老教程还在教netstat但netstat依赖/proc/net的解析连接数多的时候又慢又占资源。sssocket statistics直接读内核的 socket 信息速度飞快而且输出更清晰。我日常用的几个组合ss -antp # 查看所有 TCP 连接aall, n不解析域名, ttcp, p显示进程 ss -lntp # 只看监听端口llisten ss -s # 连接状态汇总秒级看全貌 ss -antp | grep TIME_WAIT | wc -l # 统计 TIME_WAIT 数量ss -s的输出很直观会显示当前 TCP 连接的总数以及各个状态ESTAB、TIME_WAIT、CLOSE_WAIT、SYN_SENT 等的数量。如果 CLOSE_WAIT 数量持续上涨说明应用程序没有正确关闭连接是代码问题如果 TIME_WAIT 很多在高并发短连接的场景下是正常的但也要看是否触发端口耗尽。3.2 TCP 状态机是排查的基础很多网络问题光看状态就能有初步判断。我总结了几个最常见的状态异常对应的问题状态含义常见原因SYN_SENT主动方发出 SYN没收到对方的 SYNACK对端防火墙丢包、目标 IP 不可达SYN_RECV收到 SYN回 SYNACK 后没收到 ACK半连接队列满、SYN 泛洪攻击、服务端 backlog 太小ESTAB连接正常建立无异常TIME_WAIT主动关闭方在等待 2MSL正常情况下短连接多就会出现量大要小心端口耗尽CLOSE_WAIT被动关闭方收到 FIN应用没调用 close典型的应用程序 bug连接泄漏FIN_WAIT1/2主动关闭方等待对方 ACK/FIN对端不响应可能是对端卡死比如看到大量 SYN_RECV我第一反应不是怀疑攻击而是先查应用的 backlog 是不是设置太小了。Nginx 的listen 80 backlog2048这个 backlog 参数如果小于并发连接数就很容易出现 SYN_RECV 堆积。ss -lntp可以看到当前的 Send-Q即 backlog 大小。3.3 实战排查端口明明监听了外部就是连不上有一次同事反馈某个 Java 服务端口 8080 通过ss -lntp看是 LISTEN 状态但外部怎么都连不上。我先ss -lntp看了监听地址发现是127.0.0.1:8080而不是0.0.0.0:8080。这就真相大白了——服务只监听了回环地址外部当然访问不了。改成监听0.0.0.0或具体的业务网卡地址后解决。还有一次是防火墙问题。当时ss看监听正常外部 telnet 超时。我用iptables -L -n一看发现 INPUT 链有 DROP 规则把那个网段的包丢了。所以每次排查端口连接问题我都会把本机防火墙和云安全组一起检查这两个坑太常见了。4. DNS 解析排查dig、nslookup 与 /etc/resolv.conf很多网络慢连不上的问题最后都定位到了 DNS 解析慢或者解析到错误 IP 上。这个环节很容易被漏掉但它是最常见的隐形杀手。4.1dig是最好的 DNS 排查工具nslookup很多人都用过但dig的输出详细得多能告诉你查询耗时、从哪个 DNS 服务器返回、TTL 是多少、是不是有 CNAME 链。我的标准用法dig 8.8.8.8 example.com # 指定 DNS 服务器查询 dig trace example.com # 跟踪从根域到权威域的完整解析路径 dig short example.com # 只输出解析结果 dig -x 8.8.8.8 # 反向解析PTR 记录查 IP 对应的域名dig 8.8.8.8特别好用。如果默认 DNS 解析出来的结果和指定 8.8.8.8 解析出来的结果不一样基本能判断是本地 DNS 服务器的缓存污染或更新延迟。dig trace能看到整个解析链路对排查 DNS 劫持和解析延迟非常有帮助。正常情况下从根域到顶级域再到权威域每一步都有明确的返回如果某一步超时或者返回了不该返回的 IP问题就在那一层。4.2 实战应用访问慢最后定位到 DNS 超时重试有次排查一个web 页面加载慢的问题页面等很久才出来。我先看了后端服务的响应时间都是毫秒级排除应用问题。然后curl -v访问接口发现curl卡在 Trying ... 阶段好长时间。前后一对比我怀疑是 DNS 解析慢。用dig example.com一看解析用了 4.2 秒。正常情况下局域网内 DNS 解析应该是毫秒级。我看了下/etc/resolv.confnameserver 10.10.10.1 nameserver 10.10.10.2 options timeout:1 attempts:2问题就出在这。当第一个 DNS 服务器10.10.10.1超时的时候系统要等timeout超时后再重试然后才切到第二个。这样一次解析失败最坏要等 4 秒多。后来把 DNS 换成响应快的服务器并调整了timeout和attempts页面加载恢复秒开。4.3/etc/hosts和本地缓存我排查问题时不希望它帮倒忙在测试环境很多同学喜欢在/etc/hosts里写域名映射这本来是方便调试。但有时候/etc/hosts里写了一行老的 IP会让所有线上请求都打到老的服务器上而且很难察觉。所以我排查域名解析问题时会第一时间确认/etc/hosts里有没有对该域名的硬编码。如果有优先用dig直接问指定 DNS 服务器绕过本地 hosts。5. 数据包级分析tcpdump 抓包必杀技当 ping 通、端口通、但业务还是不对劲的时候抓包是唯一能看清真相的手段。tcpdump是这门手艺的核心。5.1 抓包的第一原则别乱抓先明确要过滤什么我再强调一次不要在没有过滤条件的情况下直接tcpdump。在流量很大的生产服务器上直接抓包会瞬间生成好几个 G 的文件把磁盘写满。我通常是在问题单上先锁定源 IP、目标 IP、端口、协议然后用精准的过滤表达式抓包。tcpdump -i eth0 host 192.168.1.100 and tcp port 8080 -w /tmp/app.pcap-i eth0指定网卡host和port组合过滤条件-w写成 pcap 文件方便后续拖到 Wireshark 里看。这里有个经常踩的坑过滤器语法。and必须是大写小写and在某些版本会报错要抓端口的多种形式用port 80 or port 443记得用括号分组。5.2 经典故障定位TCP 重传和零窗口抓包最重要的意义是能看到 TCP 交互的细节。我最常用来定位两类问题第一类是 TCP 重传Retransmission。在 Wireshark 里能看到大量[TCP Retransmission]标记说明报文发出去后对端没确认超时后重发。常见原因是链路上有丢包、对端处理不过来导致缓冲区溢出。配合ss -s看重传队列Send-Q是否积压基本就能锁定问题。第二类是窗口告罄TCP Window Full和零窗口Zero Window。这通常意味着接收方的缓冲区满了应用层来不及读数据。有一次客户说文件传输速度特别慢我抓包一看服务端一直报ZeroWindow其实就是服务端的应用程序读数据太慢接收窗口被占满了。问题不在网络在应用的处理性能。5.3 抓包时别忽略 MTU 和 checksum 的坑有件事每次都要提醒如果抓包发现分片或者 checksum 报错先别急着怀疑网络。现代网卡大多开启了 TCP 校验和卸载Checksum Offload和分片卸载TSO/GRO在软件层抓的包是不完整的checksum 会显示为错误。如果确实要分析 MTU 问题用tcpdump -s 0抓完整包或者用网卡支持的大包抓取模式。另外ping -M do -s 1472 target是经典的 MTU 探测命令-M do表示不允许分片-s 1472对应 1500 的 MTU 值1500 - 20 字节 IP 头 - 8 字节 ICMP 头 1472。如果这个大小能通但-s 1473不通说明链路 MTU 刚好是 1500需要检查是不是有隧道封装额外吃了字节。6. 带宽测试与实时流量监控iperf3、nload、iftop网络调优和容量评估离不开带宽测试。这块工具比较杂我按用途分开讲。6.1iperf3给网络做“体检”iperf3是我用过最顺手的带宽压测工具专门用来测 TCP/UDP 的最大带宽和 QoS 参数。服务端iperf3 -s -p 5201客户端iperf3 -c 192.168.1.100 -p 5201 -t 30 -P 4-t 30测 30 秒-P 4用 4 条并发流测试。不加-P时只测单流带宽很多场景下单流带宽跑不满加并发更接近实际效果。iperf3结果的几个关键指标Bandwidth实际带宽、Retr重传次数、Cwnd拥塞窗口。如果Retr次数非常多说明链路上有拥塞或丢包这个链路质量是打折扣的。如果双向测速结果差异很大比如上行 900Mbps、下行 100Mbps就要怀疑是不是中继链路或对端网卡协商速率有问题。UDP 测试也有用。iperf3 -c target -u -b 500M可以测 UDP 的极限吞吐和丢包率。在排查视频会议卡顿、语音断断续续这类实时性要求高的应用时这个能直接看出链路的丢包情况。6.2nload和iftop实时看流量的“仪表盘”nload是一个简单直观的带宽监控工具进入界面后能看到当前秒级进/出流量方便快速判断服务器是否处于高流量状态。命令执行后按F2可以切换显示单位。iftop是另一类神兵利器它能显示当前每个 TCP 连接占用的带宽按流量大小排序。用来快速找到谁在疯狂占带宽非常顺手iftop -i eth0 -n -P-n不做主机名解析-P显示端口。界面会按连接排序流量大的排上面。有一次客户反馈服务器带宽耗尽我开iftop一看发现内网一台机器在向外部一个 IP 疯狂传输数据流量占了大半顺藤摸瓜查出一个数据同步任务配置错误。6.3 结合sar看历史网卡流量实时命令有时候不够用比如故障已经发生过了人没在场。这时候看历史数据很重要。sar -n DEV 1 5可以采样网卡流量sar -n DEV -f /var/log/sa/sa$(date %d -d yesterday)能查看昨天的网卡流量趋势判断故障时间点的流量是否异常。生产环境我都建议提前配好sysstat把历史数据留出来。很多网络问题都是偶发、短暂的没有历史数据就只能干瞪眼。事后追溯能力是网络排查中最容易被忽视的一环。7. 一个完整的排查实例某服务访问间歇性超时理论讲了不少最后用一个真实案例把所有工具串起来。之前的架构大概是这样Nginx 作为入口转发到后端的 Tomcat 应用。业务方反馈页面偶尔会白屏等好久才加载出来而且没有明显规律。我的排查步骤第一步先确认不是应用本身的问题。用curl -w curl-format.txt http://127.0.0.1:8080/api/test直接请求本机端口curl-format.txt里定义了输出连接时间、首字节时间、总时间的模板。结果发现本地请求都是几十毫秒返回说明 Tomcat 本身没问题。第二步从外部访问测试。curl -w再打一次 Nginx 的对外地址发现time_connectTCP 握手耗时和time_starttransfer首字节时间差别巨大。有的请求time_connect要 5 秒说明 TCP 握手阶段就卡住了。第三步ss -antp看看 ESTAB 连接和 SYN 队列情况。发现 SYN_RECV 数量异常增多同时 Nginx 的ss -lntp显示 http 的 Send-Qbacklog是默认的 511。第四步抓包确认。tcpdump -i eth0 -nn host 后端IP and tcp port 8080抓到 Nginx 发往后端的 SYN 包多次重传。这就明确了Nginx 连不上后端 Tomcat不是应用逻辑慢是 TCP 连接建立阶段有问题。第五步分析为什么。到 Tomcat 服务器上看ss -antp发现 Tomcat 的 Accept Queue 一直在满的边缘因为acceptCount默认连接等待队列长度配置太小。后端处理不过来或者 JServProtocol 的maxThreads太小导致 SYN 积压Nginx 的转发自然就超时了。最后调整了 Tomcat 的maxThreads和acceptCount问题解决。整个排查过程用到的就是分层排查思路 端口状态观测 抓包确认每一步都指向下一步。8. 常用网络排查工具速查表工具备忘我整理成一张表遇到问题先对号入座。排查目标使用的命令核心关注点基础连通性ping -c 4 target丢包率、延迟抖动端口连通性telnet IP port/nc -vz IP portConnection refused 还是 timed out路由路径traceroute -n -T -p 443 target每跳延迟断点位置持续链路监控mtr -rwz -c 100 target每跳丢包率跨运营商问题端口监听和连接ss -antp/ss -sLISTEN 状态、TIME_WAIT、CLOSE_WAITDNS 解析dig 8.8.8.8 target解析耗时、返回 IP 状态、CNAME 链数据包分析tcpdump -i eth0 host x and port y -w file.pcap重传、TCP 窗口、SYN 洪泛带宽压测iperf3 -c target -P 4 -t 30Bandwidth、Retr、Cwnd实时流量查看iftop -i eth0 -n -P谁在占带宽、按连接排序历史流量回溯sar -n DEV -f /var/log/sa/saXX故障时间点流量、误差排查9. 几个我踩过的坑和心得最后分享几个真实踩坑经验都是不容易从文档里学到的。第一个坑防火墙规则要查全。Linux 上可能是iptables、firewalld、nftables三套体系同时存在你只查了iptables -L可能漏掉 nft 的规则。查iptables -L -v -n的同时别忘了nft list ruleset。第二个坑nc扫端口的时候UDP 的结果不可靠。UDP 没有 TCP 那种三次握手nc -uz显示 open 只能说明 ICMP 端口不可达报文没触发不能证明对端真的在监听 UDP 端口。真要测 UDP用iperf3 -u或者直接让应用跑起来发数据。第三个坑抓包文件别在生产直接拖。我都是tcpdump -C 100 -W 10 -w /tmp/xx.pcap这样分块写每-C 100是 100MB 一个文件-W 10是最多写 10 个文件。防止一次性写出超大文件磁盘报警。第四个坑ss和netstat显示的监听地址不代表实际监听的网卡。我之前遇到过0.0.0.0:8080看似监听所有地址但因为网卡 down 了实际根本连接不上。这时候要看ip addr确认网卡有没有拿到 IP 并且是 up 状态。第五个心得内核参数谨慎动。网上到处都是调整 TCP 内核参数提升性能的文章但随便调大缓冲区、减小 MSL 通常会引入更多问题。没有抓包数据支撑不要改内核参数。有一次我为了提升吞吐把/proc/sys/net/ipv4/tcp_rmem调大了结果反而导致缓冲区淤积延迟变高最后改回来才恢复。内核参数调优一定是先监控、再实验、最后固化。Linux 网络调试工具不算多但每个工具用精了都能解决一大类问题。关键是脑子里的分层模型要清晰手里的命令要熟练抓到证据再下结论。按照这个思路大部分网络故障都能在半小时内定位到具体环节。