闯关预计 25 分钟
闯关:一台"网络慢"的机器
报障只有两个字"网慢"。在模拟终端里按路径逐层收敛,找出真正的原因。
学完这节你能做到
- 面对模糊报障,按固定顺序收敛而不是乱猜
- 从计数器里读出丢包发生在哪一层
- 给出一个能验证的结论,而不是"网络有问题"
建议先学跳过这几节会看不懂本节的部分推导
接手
工单原文只有一句:
我们的服务部署在
10.10.1.103上,最近偶发超时,客户端重试就好了。运维说网络没问题,ping 都是通的。
你现在 ssh 到了这台机器上。已知信息:
- 业务是高并发短请求(大量小包),单机 QPS 约 15 万
- 网卡是 25GbE,监控上带宽利用率只有 30% 左右
- 客户端在
10.10.0.51
✓怎么玩
在下面的终端里按 L0 学过的顺序敲命令。输入 goals 看目标,
hint 要提示,↑↓ 翻历史。四个目标全部达成就算过关。
别急着抓包 —— 前三层的计数器足够定位这个问题。
root@k8s-work-103
目标 0/4- 1.确认链路速率协商与状态正常
- 2.定位丢包发生在哪一层:网卡收方向还是别处
- 3.确认软中断侧是否也在丢包 / 预算耗尽
- 4.找出根因:网卡的多队列到底开了几个
Last login: Mon Aug 17 09:12:44 from 10.10.0.51 业务偶发超时,带宽利用率仅 30%。按分层顺序开始排查。
[root@k8s-work-103 ~]#
结论应该长什么样
四个目标走完,证据链是这样的:
| 证据 | 排除了什么 |
|---|---|
Speed: 25000Mb/s、Link detected: yes | 排除速率协商与链路故障 |
rx_crc_errors: 0、rx_frame_errors: 0 | 排除光模块、光纤、端口的物理问题 |
tc -s qdisc 发送侧 dropped 0 | 排除发送方向 |
rx_missed_errors / rx_no_buffer_count 在涨 | 确认丢在收方向、网卡 ring 层 |
softnet_stat 第 1 行 dropped 与 squeezed 都在涨,其余行为 0 | 确认收包全压在 CPU0 |
ethtool -l 显示 Combined: 1(硬件支持 63) | 根因:只启用了 1 个队列,RSS 散不开 |
iperf3 大流能跑 22.4 Gbps | 印证带宽不是瓶颈,PPS 才是 |
根因:网卡多队列只启用了 1 个,所有收包中断与软中断集中在 CPU0,
该核 %soft 饱和后来不及回收 rx 描述符,网卡开始丢包,触发大量 TCP 超时重传,
业务侧表现为"偶发超时"。
修法(按顺序验证,不要一次改一堆):
# 1. 把队列数打开到与 CPU 数匹配(先取 16,别一上来就 63)
ethtool -L bond0 combined 16
# 2. 确认中断散到多个 CPU 上了
cat /proc/interrupts | grep mlx5_comp | head
# 3. ring 偏浅,配合调深一档
ethtool -G bond0 rx 4096
# 4. 观察 15 分钟,确认这两个计数不再增长
watch -n5 "ethtool -S bond0 | grep -E 'rx_missed|rx_no_buffer'"
×为什么「ping 是通的」这句话没有意义
ping 每秒发几个包、每个包几十字节。这台机器的问题只在每秒十几万个小包的负载下才出现。 低速探测通过,完全不能说明高负载下不丢包。
同理,"带宽利用率只有 30%" 也是误导 —— 小包场景的瓶颈是 PPS 和单核软中断能力, 带宽图表上永远看不出来。
检查点
rx_missed_errors 在涨、而 rx_crc_errors 为 0,这组合说明什么?
/proc/net/softnet_stat 第一行的 dropped 和 time_squeeze 都在涨,其余行全是 0。下一步最该查什么?
这次故障里,下面哪些「正常指标」实际上具有误导性?(多选)
这一关的落点
- 分层收敛:链路 → 网卡计数 → 软中断 → 协议栈,每一步都在排除而不是猜测
rx_missed+crc 为 0= 主机侧跟不上,不是物理层softnet_stat只有第一行有数 = 收包挤在一个核上ethtool -l是这类问题的收官命令:硬件支持多队列,但没启用- ping 通、带宽利用率低、iperf3 跑满,这三件事都不能证明网络健康
延伸资料
- ·Systems Performance, 2nd Edition — Brendan Gregg