3. 网络问题排查:从入门到抓包

网络出问题,很多时候表现得很诡异——网页打不开、服务连不上、接口超时。你可能会先怀疑代码,然后怀疑配置,最后发现是网络层面的问题。

我个人习惯,排查网络问题有一个固定流程:先用基础命令定位范围,再用抓包工具深挖细节。今天我们就聊聊这个流程。

3.1 四大基础命令:从生疏到熟练

这四样工具,说白了就是网络排查的“手电筒”。我用它们解决过无数问题。

3.1.1 ping — 最基础的连通性测试

ping 是我用得最多的命令。没别的,就是快。

# 测试到目标主机的连通性
ping 8.8.8.8

# 指定次数,Windows 上默认只发4个包
ping -c 4 8.8.8.8

# 指定超时时间(秒)
ping -W 3 8.8.8.8

丢了几个包?延迟高不高?一眼就能看出来。

小技巧: 我曾经把 ping 当成“服务是否存活”的探针,但后来发现有些服务器会禁 ICMP。这时候 ping 不通不代表服务挂了——需要用更上层的方法验证。

你想想看,如果 ping 不通,接下来要做什么?

  • 检查网线、Wi-Fi 是否正常
  • 检查防火墙是否拦截了 ICMP
  • 检查目标主机是否在线

3.1.2 telnet — 端口的“敲门砖”

ping 只能测 IP 层的连通性。要测端口通不通,还得靠 telnet。

# 测试目标主机的 80 端口是否开放
telnet 192.168.1.100 80

如果端口通了,你会看到一个空白页面,或者服务返回一些数据。如果端口不通,telnet 会卡住然后超时报错。

注意: 很多生产环境默认不装 telnet。你可以用 nc 替代,或者装一个。我曾经在排查问题时,发现某台机器上 telnet 被安全组安全策略禁了,折腾了半天才反应过来。

3.1.3 curl — 应用层的瑞士军刀

curl 比 telnet 更进一步。它不仅能测端口,还能模拟 HTTP 请求、看响应头和 Body。

# 测试一个接口是否正常
curl -v http://192.168.1.100:8080/api/health

# 只输出响应头
curl -I https://www.example.com

# 设置超时时间
curl --connect-timeout 5 --max-time 10 http://example.com

# 模拟 POST 请求
curl -X POST -H "Content-Type: application/json" \
  -d '{"key":"value"}' http://192.168.1.100:8080/api/submit

我在项目中遇到过这样的情况:用浏览器访问一切正常,但脚本调用就是失败。我习惯第一时间用 curl -v 看请求细节,结果发现是脚本里漏了 Cookie。嗯,curl 的输出非常有用。

3.1.4 nc (netcat) — 全能的网络工具

nc 被称为网络工具里的“瑞士军刀”。端口探测、数据传输、端口监听,它都能干。

# 端口探测(比 telnet 更灵活)
nc -zv 192.168.1.100 80

# 扫描端口范围
nc -zv 192.168.1.100 20-80

# 传输文件
# 接收端
nc -l 1234 > receive.txt
# 发送端
nc 192.168.1.100 1234 < send.txt

# 测试 UDP 端口
nc -zuv 192.168.1.100 53
避坑指南: nc 的 -z 参数(Zero I/O 模式)只检查端口是否开放,不会发送数据。我曾经用 nc -zv 写了一个快速端口扫描脚本,比一个个 telnet 快多了。

3.2 基础命令排查流程

我整理了一个排查顺序,不是我凭空想的,是真在线上环境里踩过坑之后总结的。

步骤 命令 验证内容
1 ping IP 层连通性、网络延迟
2 telnet / nc 目标端口是否开放
3 curl 应用层接口是否正常
4 nslookup / dig DNS 解析是否正常
网络排查流程 网络故障 1. ping ➔ 连通性、延迟 2. telnet/nc ➔ 端口开放情况 3. curl ➔ 应用层响应 定位问题再抓包

3.3 抓包入门:tcpdump 和 Wireshark

基础命令搞不定,就得请出抓包工具了。说实话,很多人一听“抓包”就觉得难,其实从基础开始并不复杂。

3.3.1 tcpdump — 命令行抓包神器

tcpdump 没有图形界面,但绝对是排查疑难杂症的利器。

# 抓取所有经过 eth0 的包
tcpdump -i eth0

# 只抓取目标端口为 80 的包
tcpdump -i eth0 port 80

# 抓取源 IP 为 192.168.1.100 的包
tcpdump -i eth0 src host 192.168.1.100

# 组合条件:抓取到 8.8.8.8 的 DNS 请求
tcpdump -i eth0 host 8.8.8.8 and port 53

# 保存到文件,方便后续分析
tcpdump -i eth0 -w capture.pcap

我在项目中遇到过这样一个问题:某个服务偶尔超时,但 curl 能调通。用 tcpdump 抓了十分钟的包,发现是 TCP 重传导致的。

核心思路: tcpdump 抓的是原始网络包,所以它能看到 TCP 的三次握手、四次挥手、重传等底层行为。这对排查“偶发超时”这种问题特别有用。

3.3.2 Wireshark — 图形化分析工具

Wireshark 能把你抓到的 .pcap 文件加载进来,用图形界面分析。它的过滤器比 tcpdump 更直观。

# 常用过滤器表达式(在 Wireshark 里直接输入)
ip.addr == 192.168.1.100           # 只看某 IP 的包
tcp.port == 443                     # 只看 443 端口的 TCP 包
http.request.method == "POST"       # 只看 POST 请求
tcp.analysis.retransmission         # 只看重传包
!arp                                # 排除 ARP 协议
踩坑提醒: 抓包前一定要确认是在正确的网卡上抓。我刚开始学抓包时,在虚拟机上搞了半天没抓到包,后来才发现是选错了网卡。Wireshark 有个“捕获选项”界面,在那里可以看到所有网卡列表。

3.4 抓包实战案例

举个我印象很深的例子。

现象: 客户端调用服务端 API 时,偶尔会卡住 30 秒才返回结果。

排查步骤:

  1. 先 ping: 延迟正常,没有丢包
  2. 再 telnet: 端口正常
  3. curl -v: 偶尔成功,偶尔卡住
  4. tcpdump 抓包: 在客户端抓卡住时的包
# 客户端抓包
tcpdump -i eth0 host 服务端IP and port 8080 -w timeout.pcap

我用 Wireshark 打开 timeout.pcap,过滤出客户端和服务端的对话。你猜发现了什么?

TCP 三次握手成功,客户端发了请求,服务器也回了 ACK。但服务器迟迟不发送响应数据包。等了大约 28 秒,服务器才发来一个很小的数据包,然后立刻发送了 FIN 关闭连接。

说白了,问题不在网络上,在服务端代码上——某个连接池配置了 30 秒超时,但代码里没有正确处理。抓包帮我直接排除了网络层面的嫌疑。

个人习惯: 我现在遇到“偶发超时”的问题,第一反应就是抓包。别猜,看看网络上到底发生了什么。数据不会说谎。

3.5 常见问题排查表

这张表我贴在工位上很久了,现在分享给你。

现象 可能原因 排查命令
ping 不通 网线、防火墙、IP 错误 ping, ifconfig
telnet 连不上 端口未开放、防火墙拦截 telnet, nc -zv
curl 返回超时 网络延迟、服务端慢 curl -v, tcpdump
偶尔连不上 DNS 缓存、连接池耗尽 nslookup, netstat
数据丢失 TCP 重传、丢包率高 tcpdump, Wireshark

记住,排查网络问题时,从底层往上推。ICMP 不通就看 IP 和物理层;端口不通就看防火墙;应用层出问题就看 curl 的响应。抓包是最后的手段,但往往最关键。