典型的场面:用户说网站慢,运维说服务器负载正常,开发说接口响应只有 80 毫秒,然后大家一起看网络组。
这种时候抓个包,十分钟能出结论。前提是知道看哪三个数。
这篇讲排查顺序,不讲 TCP 协议本身。你要是还没搞清三次握手长什么样,先去看基础,这篇会有点跳。
先排除掉不属于网络的部分
很多人一上来就看丢包,其实问题经常在别处。打开抓包文件,先看时间轴:
tshark -r cap.pcapng -Y "tcp.flags.syn==1 and tcp.flags.ack==0" \
-T fields -e frame.time_relative -e ip.dst -e tcp.dstport
看第一个 SYN 到第一个业务数据之间隔了多久。如果这个间隔有两三百毫秒,那跟你抓的这个服务没关系,是 DNS 或者建连慢。
再看服务端的响应时间。在 Wireshark 里选中一个请求,看它到对应响应之间差多少——这个数字就是 TTFB。如果已经是 800 毫秒,那后面什么重传窗口都不用看了,问题在后端。
我一般先用 Statistics → HTTP → Requests 或者 tshark -z http,tree 把每个请求的耗时列出来,找出最慢的那几个,再去看它们的 TCP 细节。反过来做,容易在几千个包里迷路。
指标一:重传率
重传是丢包最直接的证据。
tshark -q -z io,stat,1,"tcp.analysis.retransmission" -r cap.pcapng
输出是每秒的重传数量。单独看这个数字没意义,要看比例:
tshark -r cap.pcapng -Y "tcp.analysis.retransmission" | wc -l
tshark -r cap.pcapng -Y "tcp" | wc -l
两个一除。经验上:
低于 0.1% —— 正常,公网必然有一点。
0.5% 到 2% —— 已经开始影响体验,尤其是短连接。
超过 2% —— 有问题,去看丢在哪一跳。
光看总量不够,还得看类型。Wireshark 把重传分了好几种,最该区分的是这两个:
tcp.analysis.retransmission 是超时重传,说明等不到 ACK,通常意味着包真的丢了。
tcp.analysis.fast_retransmission 是收到三个重复 ACK 后立刻重发,说明后面的包到了、中间那个没到。这种情况恢复快,对性能影响小很多。
如果全是 fast retransmission,说明是偶发丢包,链路质量一般但还能用。如果全是超时重传,那就是真丢了,或者对端根本没在处理。
还有一种容易误判的:tcp.analysis.spurious_retransmission,重传了但其实没必要,通常是抓包点位置导致的错觉(比如在发送端抓,包已经出去了但 ACK 还没回来)。看到这个不要慌,先确认抓包位置。
指标二:窗口
这个比重传更常被忽略,但它能告诉你一个关键区别:是网络塞不下,还是对面来不及收。
tcp.analysis.zero_window
过滤器里敲这个,如果跳出来一堆,结论已经很明确了:接收方的缓冲区满了,应用层没及时读数据。
这时候网络是通的,包也送到了,只是收的一方处理不过来。常见原因是应用在处理上一个请求时阻塞了,或者线程池满了,或者磁盘 IO 卡住。
零窗口之后通常会跟一个 tcp.analysis.window_update,那是应用终于把数据读走了,窗口重新打开。两者之间的时间差,就是应用卡了多久。
看窗口还有一个地方:Statistics → TCP Stream Graphs → Window Scaling。图上如果窗口值一路往下掉到接近零,然后突然弹回来,就是这个模式。
指标三:带宽延迟积
这个是最经典的”配置问题导致性能上不去”。
TCP 的吞吐量上限大约是 窗口大小 ÷ RTT。默认窗口 64KB,如果 RTT 是 100 毫秒,理论上限就是 64KB / 0.1s ≈ 5 Mbps。
也就是说,一条千兆链路,跨省 100 毫秒延迟,单条 TCP 连接最多跑到 5 Mbps。这不是带宽不够,是窗口不够。
解决办法是窗口缩放(Window Scaling),在 SYN 握手时协商。现在主流系统默认都开了,但有两种情况会失效:
一是中间有老设备把 TCP 选项剥掉了。二是抓包点在做 NAT,某些实现会重写窗口字段。
在 Wireshark 里看握手包:tcp.window_size_scalefactor 如果是 -1,说明没协商成功,窗口就是死的 64KB。
顺带说一个经常被搞混的:tcp.window_size_value 是未经缩放的原值,tcp.window_size 才是乘过缩放因子的实际值。看图的时候看错字段,结论会完全反过来。
那个永远被忽略的 MTU
症状很好认:小请求正常,一传大文件就卡死或者超时。
典型场景是 VPN、PPPoE、或者中间有隧道。MTU 从 1500 降到 1400 多,如果两端没正确协商 MSS,大包会被丢弃,而且丢得悄无声息——因为路径 MTU 发现依赖 ICMP,而 ICMP 经常被防火墙拦。
判断方法:
ping -M do -s 1472 目标IP
1472 + 28 = 1500。能通说明 MTU 正常;报 Message too long 就是超了。往下试 1400、1300,找到临界值。
抓包侧的证据是:看到大量 1500 字节的包被重传,而小包都正常,同时伴随 tcp.analysis.retransmission 集中在 DATA 阶段。这种情况不用怀疑应用,去查 MTU。
根治办法是把两端的 MSS clamp 到路径 MTU 以下,而不是关掉路径 MTU 发现。
排查顺序
说了这么多,实际动手是有顺序的,顺序错了会绕远路。
先看 TTFB。如果服务端自己在 500 毫秒以上,后面全都不用看。
TTFB 正常但总耗时高,再分两种情况:传输阶段慢,还是等待阶段慢。在 Wireshark 里看最后一个 ACK 和第一个响应字节之间的间隔,如果这段空白很长,是服务端在算;如果这段有数据但很慢,才是网络。
确认是网络之后,先看重传率,再看零窗口。这两个能覆盖八成情况。
重传正常、窗口正常,但吞吐就是上不去——这时候才轮到 BDP 和 MTU。这两个是”配置型”问题,不常见,但一旦碰上,前面所有指标看起来都正常。
最后
做了几年这类排查,我的经验是:大部分”网络慢”最后不是网络问题。
数据库慢查询、锁等待、GC 停顿、同步调用第三方,这些在抓包里表现都是”等待”——服务端收完请求,很久才吐第一个字节。看起来像网络慢,其实是应用卡住。
抓包的价值不是证明网络有问题,是能快速证明网络没问题,然后把注意力挪到该去的地方。这个作用经常被低估。
抓包分析仅限自有服务与授权范围。生产环境抓包前评估磁盘与性能影响,用 dumpcap 加环形缓冲,别长时间全量抓。
- 1、本网站名称: 星宇安全实验室
- 2、本站永久网址:https://bk.zhaozhiqiang.pw/
- 3、本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
- 4、本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
- 5、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
- 6、本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。
- 7、文章版权归作者所有,未经允许请勿转载。















暂无评论内容