Appearance
网络诊断与排错
网络故障排查有个铁律:从下往上、一层层收敛——地址 → 路由 → DNS → 端口 → 协议响应 → 抓包。每一步用对应的工具,不跳层、不乱序。底层断了上层肯定不通,跳过底层直接查上层,排查方向就跑偏了。这篇按这个顺序把每一步的工具和判断方法过一遍。
一、收集基础信息
排查网络问题,先用四个命令把本机的网络基本面摸清楚:
bash
ip addr # 网卡有没有 UP、IP 对不对
ip route # 默认路由和静态路由是否正确
cat /etc/resolv.conf # DNS 指向哪里
ss -lntp # 哪些服务在监听哪些端口很多问题到这一步就已经暴露了,根本不需要继续往下查。比如发现网卡是 DOWN 状态、路由表里没有默认路由、服务没监听对应端口——这些都是一眼能看出来的底层问题。
二、ping
bash
ping -c 4 8.8.8.8 # ping IP
ping -c 4 example.com # ping 域名ping 的判断逻辑很直接:能 ping 通 IP 但 ping 不通域名,是 DNS 问题;IP 也 ping 不通,继续排查路由、防火墙、云安全组。
但 ping 有个局限性要记住:它用的是 ICMP 协议,有些服务器和网络设备会主动禁 ICMP(出于安全或者防探测),所以 ping 不通不代表业务端口不通。HTTP、SSH 这些业务服务还是要直接测端口连通性,不能光靠 ping 下结论。
三、traceroute 和 mtr
traceroute 显示数据包经过的路径,看流量每一跳走到哪:
bash
traceroute 8.8.8.8mtr 是 traceroute + ping 的合体版,持续统计每一跳的丢包率和延迟,比 traceroute 的单次快照强得多,排查网络质量问题首选:
bash
mtr 8.8.8.8
mtr -rw 8.8.8.8 # -r 报告模式,-w 宽输出,适合截图存档安装:
bash
yum install traceroute mtr -y
apt install traceroute mtr -y看 mtr 输出有个特别容易误判的点:中间某一跳丢包率高,不一定是那台路由器有问题。很多路由器会限制 ICMP 回复速率,或者直接不回复中间跳的探测——这叫"ICMP 限速"。真正要看的,是最终目的地址有没有丢包、延迟正不正常。中间跳丢包但终点正常,基本是 ICMP 限速造成的假象,不是真故障。
四、curl 测试 HTTP
HTTP 层排查优先用 curl,它是 HTTP 客户端的事实标准,比浏览器方便、比 telnet 信息全:
bash
curl -I http://example.com # 只看响应头
curl -v http://example.com # 看完整的请求-响应过程
curl -fsS http://127.0.0.1:8080/healthz # 静默但保留错误,健康检查常用几个高频参数:-I 只看响应头、-v 显示连接全过程(DNS 解析、TLS 握手、请求头)、-f 收到 4xx/5xx 时退出码设为失败、-sS 静默但保留错误、-L 自动跟随重定向、-k 忽略 TLS 证书校验(测试用,生产脚本别加)。
脚本里做健康检查的典型写法是 curl -fsS http://127.0.0.1:8080/healthz——失败时有非零退出码(脚本能判断),也有错误输出(能看到为什么失败),监控和排错都方便。
五、DNS 诊断
bash
getent hosts example.com # 走系统 NSS,模拟应用真实的解析路径
dig example.com # 直接查 DNS,绕过 hosts 和缓存
dig @8.8.8.8 example.com # 指定用某个 DNS 服务器做对比排查 DNS 问题,要同时关注两个配置文件:
bash
cat /etc/nsswitch.conf # 看解析顺序(files 在 dns 前还是后)
cat /etc/resolv.conf # 看当前用的 DNS 服务器/etc/hosts 写死旧 IP 是 DNS 排查里的经典老问题:dig 出来已经是新 IP 了,但应用层还在连旧 IP——原因就是 nsswitch 里 files(/etc/hosts)排在 dns 前面,hosts 里的旧地址优先级更高。所以排查 DNS 异常,getent hosts(走完整解析路径)和 dig(只查 DNS)要对比着看,两边结果不一样,八成是 hosts 或者 nsswitch 的问题。
六、ss 查看连接
ss 是查看本机网络连接的主力工具(取代了老的 netstat)。
看本机监听的端口:
bash
ss -lntp # -l 监听,-n 不解析名称(快),-t TCP,-p 显示进程看所有 TCP 连接,比如查谁连了 MySQL:
bash
ss -antp | grep ':3306'TCP 连接状态要能看懂几个关键的:LISTEN 正在监听等连接、ESTAB 连接已建立正在传数据、TIME-WAIT 连接已关闭等残留包超时、SYN-SENT 客户端发了 SYN 等回应、SYN-RECV 服务端收到 SYN 等 ACK。
根据连接状态能快速定位问题方向:大量 SYN-SENT 说明客户端发出的 SYN 收不到回应(对端不可达或者被防火墙拦了);大量 TIME-WAIT 倒不一定是问题——它是 TCP 的正常收尾状态,高并发短连接场景下特别多。但如果同时出现端口耗尽(本地临时端口用光了,新连接建不起来),就得调整内核参数(比如 net.ipv4.tcp_tw_reuse)或者改用长连接了。
七、tcpdump 抓包
抓包是最后一层手段,用之前要尽量把问题范围缩小——因为抓包信息量大、看起来累,前面几层能定位的就不要上抓包。
bash
tcpdump -i eth0 host 10.0.0.1 # 只看与 10.0.0.1 通信的包
tcpdump -i eth0 port 80 # 只看 80 端口的包
tcpdump -i eth0 host 10.0.0.1 and port 443 # 两个条件取交集
tcpdump -i eth0 -w /tmp/debug.pcap host 10.0.0.1 # 保存到 pcap 文件(给 Wireshark 分析)
tcpdump -i eth0 -c 100 port 53 # 抓 100 个包后自动停止生产环境抓包一定要控制过滤条件和抓包时长。不设过滤的全量抓包,几个 G 的文件几分钟就生成,而且可能捕获到业务敏感数据(密码、token、用户信息)。抓之前明确要抓什么(哪个 IP、哪个端口、多长时间),抓完立刻停。
八、排错的统一顺序
把前面所有步骤串成一个标准的排查流程:
| 步骤 | 用什么命令 | 确认什么 |
|---|---|---|
| 本机地址 | ip addr | 网卡 UP 没、IP 和掩码对不对 |
| 路由 | ip route | 默认路由在不在、有没有冲突路由 |
| DNS | getent hosts <domain> | 域名能不能解析、解析结果对不对 |
| 本机端口 | ss -lntp | 服务监听了没、监听地址对不对 |
| 本机访问 | curl http://127.0.0.1:port | 回环能不能访问(排除网络层问题) |
| 远端访问 | curl http://server:port | 跨网络能不能访问 |
| 抓包 | tcpdump | 数据包实际断在哪一层 |
排查过程中,有两个诊断结果最有价值,一定要分清:
Connection refused:包已经到达目标机器了,但目标端口没有服务监听(或者被主动拒绝)。问题在服务端——服务没起来、端口错了。Connection timed out:包根本没到目标,或者回包回不来。问题在网络路径——路由不通、防火墙丢弃、安全组没放行、目标机器不在线。
把这两种情况分清楚,后续排查方向就不会跑偏。refused 去查服务端,timed out 去查网络链路,这是网络排错最基本也最重要的判断。