这是《计算机网络 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 应用发送一个字节到网卡收到数据,中间会经历系统调用、协议栈、路由、Netfilter、qdisc、DMA、硬中断、软中断和协议解析。理解内核网络栈,才能解释 softirq 高、丢包、队列延迟、conntrack 满和 CPU 分布不均。
27.1 接收路径
网卡收到帧
-> DMA 到 RX Ring Buffer
-> 硬中断
-> NAPI 轮询
-> 软中断 NET_RX
-> IP 层
-> Netfilter / Conntrack
-> TCP / UDP
-> Socket Receive Queue
-> 应用 read()
关键点:
- Ring Buffer 大小有限;
- 硬中断只做通知,处理在软中断;
- NAPI 在高负载下从中断切换到轮询;
- 应用读取慢会造成 socket 队列堆积;
- conntrack 会增加每包成本;
- softnet 丢包说明 CPU 来不及处理。
查看:
cat /proc/interrupts
cat /proc/net/softnet_stat
ethtool -S eth0
27.2 发送路径
应用 write()
-> Socket Send Buffer
-> TCP 分段
-> IP 路由
-> Netfilter
-> QDisc
-> NIC TX Ring
-> 网卡发送
如果发送缓冲满,write 可能阻塞或返回 EAGAIN,取决于文件描述符模式。
查看:
ss -i
tc -s qdisc show dev eth0
ethtool -S eth0
27.3 NAPI
NAPI 是中断和轮询的混合机制:
低流量:中断驱动,延迟低
高流量:关闭或减少中断,批量轮询,减少 CPU 开销
收益:
- 减少每个包一次中断的开销;
- 批量处理描述符;
- 提升高包量吞吐;
调优通常不是直接修改 NAPI,而是关注:
- RSS 队列;
- 中断亲和;
- Ring Buffer;
- softnet 分布;
- 协议处理 CPU。
27.4 RSS 与中断亲和
RSS 将流量哈希到多个网卡队列:
NIC RX Queue 0 -> CPU 0
NIC RX Queue 1 -> CPU 1
NIC RX Queue 2 -> CPU 2
NIC RX Queue 3 -> CPU 3
查看队列:
ethtool -l eth0
查看中断:
grep eth0 /proc/interrupts
cat /proc/irq/<irq>/smp_affinity_list
问题:
- 只有单队列,单核 softirq 高;
- 中断集中在少数 CPU;
- 队列数超过业务需要;
- NUMA 跨节点访问;
- 云实例规格限流。
可配合 RPS / RFS 将包调度到其他 CPU:
cat /sys/class/net/eth0/queues/rx-0/rps_cpus
27.5 QDisc
QDisc 是内核流量调度队列。
查看:
tc qdisc show
tc -s qdisc show dev eth0
常见:
| QDisc | 特点 |
|---|---|
| fq_codel | 控制队列延迟 |
| fq | 公平队列,配合 BBR |
| pfifo_fast | 先进先出 |
| tbf | 限速 |
| htb | 层级带宽控制 |
生产可用 tc 做备份限速或测试,但大规模策略应由云网络、CNI 或专用网关管理。
27.6 Netfilter 与 conntrack
Netfilter 钩子:
PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING
conntrack 记录连接状态:
src=10.0.1.10 dst=1.2.3.4 sport=50000 dport=443 state=ESTABLISHED
查看:
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
conntrack -S
高并发容器宿主机要监控:
- conntrack count;
- insert failed;
- drop;
- table full;
- 新建连接速率;
- 空闲超时。
27.7 常用观测工具
系统层:
mpstat -P ALL 1
vmstat 1
watch -d cat /proc/net/softnet_stat
网络层:
ss -s
ss -antp
ss -i
nstat -az
netstat -s
追踪工具:
| 工具 | 用途 |
|---|---|
| tcpdump | 包级事实 |
| bpftrace | 内核函数追踪 |
| perf | CPU 热点和软中断 |
| ethtool | 网卡统计和队列 |
| biolatency / biosnoop | 存储侧排查 |
27.8 调优原则
先定位:
丢包发生在哪里?
CPU 忙在哪里?
队列堆积在哪里?
延迟来自哪里?
再行动:
- softnet 丢包:增加队列、调整 RSS、优化应用;
- Ring Buffer 溢出:适度增大,同时关注延迟;
- conntrack 满:扩容或减少连接;
- 中断集中:设置亲和;
- 应用读取慢:优化 IO 模型;
- 带宽打满:限流或扩容;
- 队列延迟:更换 qdisc;
- 云实例限流:升级规格。
本章小结
Linux 网络栈接收路径经过网卡 DMA、硬中断、NAPI、软中断、协议栈、Netfilter 和 socket 队列;发送路径经过 socket 缓冲、协议栈、QDisc 和网卡队列。softnet、Ring Buffer、RSS、中断亲和、conntrack 和 qdisc 是内核层排障重点。调优必须基于丢包位置和 CPU 热点,而不是盲目改参数。
思考题
- 硬中断和软中断在网络收包中分别负责什么?
- NAPI 为什么能降低高流量下的 CPU 开销?
- conntrack 表满会造成什么?
- fq_codel 对缓冲膨胀有什么帮助?
- 写一份高 PPS 宿主机的内核网络观测清单。