收包积压队列是什么
net.core.netdev_max_backlog 限制每个 CPU 的收包积压队列长度,默认 1000。网卡把数据包通过中断与轮询交给内核后,如果协议栈处理不过来,包会先排在这个队列里;队列满了就直接丢弃,且不会通知对端。小包高 PPS 的场景(DNS、短连接网关、压测被打端)最容易触发,表现为抓包显示对端已发出但本机协议栈没有收到,重传与超时随之上升。
基本信息
| 参数 | net.core.netdev_max_backlog |
|---|---|
| 默认值 | 1000 |
| 作用粒度 | 每个 CPU 一条队列,不是全局共享 |
| 溢出统计 | /proc/net/softnet_stat 中的丢弃列,数值为十六进制 |
| 常见症状 | 高 PPS 下丢包、重传上升,而带宽利用率并不高 |
| 相关方向 | 网卡多队列、中断与 RPS 配置是否合理 |
典型使用场景
- DNS 与短连接网关:单包处理的请求量大,协议栈处理速率成为瓶颈
- 压测被打端:用工具打高 PPS 时出现丢包,需要判断是队列积压还是网卡本身
- 排查神秘丢包:对端确认已发送、本机应用侧看不到,先在 softnet_stat 里找证据
- 万兆及以上网卡调优:默认 1000 在高 PPS 下明显偏小
- 虚拟化环境:vhost 与 virtio 路径上的包处理同样受该队列影响
查看与调整
查看与调整
sysctl net.core.netdev_max_backlog # 读当前上限
awk '{print $1, $2, $3}' /proc/net/softnet_stat | head # 处理数 丢弃数 time_squeeze
cat /proc/net/softnet_stat | wc -l # 行数对应 CPU 数量
sysctl -w net.core.netdev_max_backlog=16384 # 临时调大
sysctl net.core.dev_weight # 相关参数:每轮轮询处理的最大包数落盘与回读
落盘与回读
# /etc/sysctl.d/99-net-tuning.conf
net.core.netdev_max_backlog = 16384 # 高 PPS 场景抬高收包积压上限
# 回读命令:sysctl net.core.netdev_max_backlogsoftnet_stat 列读法
| 列 | 含义 | 判读要点 |
|---|---|---|
| 第一列 | 已处理的包数 | 用于建立基线,判断流量规模 |
| 第二列 | 因队列满而丢弃的包数 | 持续增长说明积压队列确实不够 |
| 第三列 | 一轮轮询内未处理完的次数 | 增长说明单次轮询的预算不足,与 CPU 处理能力相关 |
| 行号 | 对应 CPU 编号 | 只有个别行增长时说明中断或收包集中在特定核 |
调大积压队列只是加深缓冲:包在队列里排队越久,延迟越高,极端情况下应用收到的是已经过时的数据。根因通常是软中断处理分布不均或单核能力不足,先核对网卡多队列、中断亲和性与 RPS 配置再考虑调参数。
softnet_stat 的数值以十六进制打印,直接用十进制阅读会得出错误结论。核对前先换算,或观察同一列在不同时间点的增量趋势,避免被数字表象误导。