排障与可观测:ping、traceroute、tcpdump、Wireshark
这一课你将能做到
- 用「四段定位法」在 15 分钟内把「网站打不开」缩小到具体环节
- 熟练组合 ping / mtr / curl / tcpdump 四件套取证
- 读懂一次抓包:三次握手、TLS 握手、重传、RST 各意味着什么
为什么要学
网络排障是网工的看家本领,也是后端进阶的分水岭。故障降临时,工具链就是你的眼睛。本课方法论来自真实场景:Nginx 入口、K8s 集群、云上部署——本站的每条命令都可以直接抄去用。
先建立图像
一次「用户说网站打不开」的完整链路与观测点:
用户终端 ──WiFi── 路由器 ──ISP── CDN/LB ── Nginx ── K8s Pod
│ │ │ │ │ │
DNS解析 信号 出口 回源/证书 转发/超时 服务监听
▼ ▼ ▼ ▼ ▼ ▼
dig iw link mtr curl -v nginx日志 kubectl/tcpdump
排障心法:先问范围(都慢还是个别人慢?),再按四段走:
DNS → TCP → TLS → HTTP,每段一条命令一个结论,不靠猜。
跟着做
步骤 1:四段定位法
DOMAIN=你的域名
dig +short $DOMAIN # ① DNS:有没有解析
curl -sv -o /dev/null --connect-timeout 3 "http://$DOMAIN" 2>&1 | grep -E 'Trying|Connected' # ② TCP
curl -sv -o /dev/null "https://$DOMAIN" 2>&1 | grep -E 'SSL connection|subject' # ③ TLS
curl -s -o /dev/null -w '%{http_code} %{time_total}s\n' "https://$DOMAIN" # ④ HTTP
四行输出对应四类故障:解析失败 / 连接超时 / 证书问题 / 应用慢或错。
步骤 2:路径质量(mtr 优于 traceroute)
mtr -n -rw -c 50 你的服务器IP
看三列:Loss%(丢包集中在哪跳)、Avg(延迟增量)、StDev(抖动)。中间跳丢包但末端干净 = 中间设备对 ICMP 限速,是假象;末端丢包才是真问题。
步骤 3:抓包取证(场景:Nginx 502)
# 在 K8s 节点抓回源端口
sudo tcpdump -i any -nn -w /tmp/502.pcap 'tcp and port 8443'
# 复现后 Wireshark 打开,过滤器:tcp.analysis.retransmission
# SYN 发出无响应 → Pod 崩了或 NetworkPolicy 拦截
# 收到 RST → 后端进程拒绝,转应用日志
步骤 4:Wireshark 常用过滤器(背下这六个)
http 只看 HTTP
tls.handshake.type == 1 Client Hello(TLS 握手起点)
tcp.flags.reset == 1 谁发了 RST
tcp.analysis.retransmission 重传(丢包 / 乱序)
tcp.analysis.zero_window 接收方处理不过来
dns.qry.name contains "你的域名" 定位 DNS 查询
步骤 5:可观测留底
# Nginx:慢请求日志(区分入口耗时与后端耗时)
log_format timing '$remote_addr $request_time $upstream_response_time $status $request';
# 云上:VPC 流日志 + LB 访问日志平时就开,事后取证靠它们
讲清楚要点
- 排障流程固定五步:明确现象 → 圈定范围 → 分层定位 → 抓包取证 → 复盘沉淀;顺序错了全程低效。
- ping 只证 ICMP 可达,不等于服务可用;端口探测(curl/telnet/nc)才是传输层真相。
- traceroute 每跳默认发三个探测包;中间跳异常未必是真丢包(ICMP 限速),以末端为准。
- tcpdump 先过滤再抓:BPF 表达式
host / port / and / or / not;-w落盘离线分析,避免线上刷屏。 - 观测要前置:流日志、LB 日志、慢请求日志平时就开——「事后开监控」等于案发后才装摄像头。
你可能会懵的地方
-
ping 通但服务连不上,说明什么? ICMP 通 = 三层可达;连不上 = 四层及以上问题:端口没监听、安全组拦、应用假死。直接
ss -tlnp与 curl 探端口。 -
抓包应该在哪抓? 原则:链路两端各抓一次,对比谁收发异常。K8s 里优先宿主机网卡(能看所有 Pod 流量)加端口过滤。
-
RST 和超时含义差别? RST = 明确拒绝(进程没起 / 端口关闭 / REJECT),立刻失败;超时 = 包石沉大海(丢包 / 静默 DROP / 不可达)。两者排查方向完全不同。
-
time_total 高但 upstream_response_time 低,锅在哪? 前者是整个请求耗时,后者是后端处理时间;差值耗在 Nginx 自身(TLS、缓冲、排队)。这是本站判断「慢在入口还是应用」的标准判据。
-
偶发毛刺(超时)怎么查? 长周期数据说话:mtr 定时任务、upstream_response_time 分位数、节点间 ping 记录;毛刺几乎都是拥塞 / 重传 / GC / 调度四选一,靠数据排除。
错法对照
| 错法 | 问题 | 正解 |
|---|---|---|
| 不问范围就开查 | 单人问题查全局,白费 | 先确定影响面:自测、他人、监控 |
| 生产乱抓包不看过滤 | 全量包压垮网卡与磁盘 | BPF 过滤 + -c 限量 + -w 落盘 |
| 看到 502 直接重启 Nginx | 掩盖后端真因 | 看 error.log:refused 还是 timeout 分流查 |
| 测一次就下结论 | 毛刺型故障漏网 | mtr / 长压测 / 分位统计,看分布 |
| 忽略 MTU | 大包卡死而小包正常 | ping -M do -s 1472 探路径 MTU |
卡点急救
- curl 卡住不返回:加
--connect-timeout 3 --max-time 10,把「无响应」变成「有结论」。 - tcpdump 噪音太大:
not port 22 and not arp先降噪,或直接host 目标IP。 - pcap 文件巨大:
editcap -c 100000 big.pcap small.pcap切分,或用 capinfos 先看时间范围再过滤。
面试常问
-
一次完整的网络故障排查流程? 影响面 → 四段定位(DNS/TCP/TLS/HTTP)→ 工具取证(dig/mtr/curl/tcpdump)→ 修复验证 → 复盘补监控。重点讲「每一步的判据」,不是罗列命令。
-
TCP 重传风暴怎么定位丢包点? mtr 看路径丢包分布 → 两端 tcpdump 统计重传与乱序 → 对比两侧序列号确认「发出未达」还是「达未确认」→ 结合交换机 / 网卡计数器收口。
-
如何区分慢在入口层还是应用层? 对比 Nginx 的 $request_time 与 $upstream_response_time:差值大 = 入口 / TLS / 排队;两者都大 = 后端,再配合 APM 收口。
自测三问
- 四段定位法是哪四段,各用什么命令?
- mtr 中间跳丢包 60% 但末端 0%,结论是什么?
- Nginx 日志里 request_time 与 upstream_response_time 的差值说明什么?
小结一句话
排障是「用命令拿证据、按分层定范围」:先有方法论,工具才有意义。
延伸
- Wireshark 官方用户手册
- 下一课:认证与学习路径——CCNA、HCIA 与云认证怎么选。