这篇文章上次修改于 899 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
ping 工具可用来定位网络延迟问题,当 ping 本身也出现了问题时,需要抓取 ping 命令的收发包,进行分析并找出问题原因。
tcpdump 和 Wireshark 是常用的网络抓包工具:
- tcmdump 仅支持命令行格式,常用在服务器端。
- Wireshark 除了抓包外,还提供界面和汇总分析工具。
安装:
$ sudo apt install tcpdump wireshark
1 现象
# ping 3 次(默认每次发送间隔1秒)
$ ping -c3 geektime.org
PING geektime.org (35.190.27.188) 56(84) bytes of data.
64 bytes from 35.190.27.188 (35.190.27.188): icmp_seq=1 ttl=43 time=36.8 ms
64 bytes from 35.190.27.188 (35.190.27.188): icmp_seq=2 ttl=43 time=31.1 ms
64 bytes from 35.190.27.188 (35.190.27.188): icmp_seq=3 ttl=43 time=31.2 ms
--- geektime.org ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 11049ms
rtt min/avg/max/mdev = 31.146/33.074/36.809/2.649 ms
可以看懂,。3 次发送,收到 3 次响应,没有丢包,但三次发送和接受的总时间居然超过了 11s(11049ms)。
2 排查
查看是否是 DNS 解析问题:
$ time nslookup geektime.org
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: geektime.org
Address: 35.190.27.188
real 0m0.018s
user 0m0.006s
sys 0m0.000s
域名解析还是很快的,只需要 18ms。
打开另一个终端,采用 tcpdump 抓包,并且在之前的终端重新执行 ping.
# -nn 不解析抓包中的域名、端口号和协议
# udp port 53,只显示 udp 端口号为 53 的包,包括源端口和目的端口
# host 35.190.27.188,只显示 IP 为 35.190.27.188 的包,包括源 IP 和目的 IP
$ tcpdump -nn udp port 53 or host 35.190.27.188
cpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
14:02:31.100564 IP 172.16.3.4.56669 > 114.114.114.114.53: 36909+ A? geektime.org. (30)
14:02:31.507699 IP 114.114.114.114.53 > 172.16.3.4.56669: 36909 1/0/0 A 35.190.27.188 (46)
14:02:31.508164 IP 172.16.3.4 > 35.190.27.188: ICMP echo request, id 4356, seq 1, length 64
14:02:31.539667 IP 35.190.27.188 > 172.16.3.4: ICMP echo reply, id 4356, seq 1, length 64
14:02:31.539995 IP 172.16.3.4.60254 > 114.114.114.114.53: 49932+ PTR? 188.27.190.35.in-addr.arpa. (44)
14:02:36.545104 IP 172.16.3.4.60254 > 114.114.114.114.53: 49932+ PTR? 188.27.190.35.in-addr.arpa. (44)
14:02:41.551284 IP 172.16.3.4 > 35.190.27.188: ICMP echo request, id 4356, seq 2, length 64
14:02:41.582363 IP 35.190.27.188 > 172.16.3.4: ICMP echo reply, id 4356, seq 2, length 64
14:02:42.552506 IP 172.16.3.4 > 35.190.27.188: ICMP echo request, id 4356, seq 3, length 64
14:02:42.583646 IP 35.190.27.188 > 172.16.3.4: ICMP echo reply, id 4356, seq 3, length 64
第 1 条,表示发往 114.114.114.114 的 A 记录查询请求。
- 36909+ 是查询标识,+ 表示启动递归查询。
- A? 表示查询 A 记录。
- 30 表示报文长度。
- 第 2 条,返回 DNS 响应。
- 第 3、4 条,分别为 ICMP echo request 和 ICMP echo reply,时间戳相减为 ICMP 所需时间,为 30ms,没有问题。
- 第 5、6 条,为反向地址解析请求,即从 IP 反查域名。没有响应包,且都是超时 5s 后才发出下一条请求。
- 后面的 4 个包是两个正常的 ICMP 请求,耗时正常。
所以,是 PTR 有问题,并不是所有的 IP 都会定义 PTR 记录。禁调 PTR 即可:
$ ping -n -c3 geektime.org
PING geektime.org (35.190.27.188) 56(84) bytes of data.
64 比特,来自 35.190.27.188: icmp_seq=1 ttl=107 时间=48.0 毫秒
64 比特,来自 35.190.27.188: icmp_seq=2 ttl=107 时间=47.1 毫秒
64 比特,来自 35.190.27.188: icmp_seq=3 ttl=107 时间=47.8 毫秒
--- geektime.org ping 统计 ---
已发送 3 个包, 已接收 3 个包, 0% 包丢失, 耗时 2002 毫秒
rtt min/avg/max/mdev = 47.126/47.623/47.972/0.361 ms
现在只需要耗时 2s 即可。
但是 tcpdump 的输出不太规整,可以先将其输出保存下来:
$ tcpdump -nn udp port 53 or host 35.190.27.188 -w ping.pcap
然后采用 Wireshark 打开,不仅以更规整的格式,展示了各个网络包的头部信息;还用了不同颜色,展示 DNS 和 ICMP 这两种不同的协议。你也可以一眼看出,中间的两条 PTR 查询并没有响应包。
参考
倪朋飞. Linux 性能优化实战.
没有评论