Linux 网络栈缩写全解析
运维 / 内核调优 / 排障工程师必读 · 阅读约 9 分钟
把 Linux 网络栈想象成一座繁忙的港口:包是集装箱,CPU 是码头工人,网卡是起重机。那些三字母缩写,就是港口里的自动化设备——有的负责分包,有的负责合包,有的调度 CPU,有的减少中断。把它们搞清楚,80% 的网络性能问题就有了定位方向。
一、数据包分段与聚合
这组机制决定大包如何拆、小包如何合,对吞吐量影响最直接。
| 缩写 | 全称 | 方向 | 实现 | 作用 |
|---|---|---|---|---|
| SG | Scatter-Gather I/O | 发送 | NIC 硬件 | 允许网卡从分散内存直接 DMA,是 TSO 正常工作的前提 |
| TSO | TCP Segmentation Offload | 发送 | NIC 硬件 | 网卡负责 TCP 分段,降低 CPU 负载 |
| GSO | Generic Segmentation Offload | 发送 | Kernel 软件 | 内核延迟分段框架:网卡支持 TSO 则直接卸载,不支持时软件兜底 |
| GRO | Generic Receive Offload | 接收 | Kernel 软件 | 接收包合并,减少协议栈处理次数,默认开启,现代推荐方案 |
| LRO | Large Receive Offload | 接收 | NIC 硬件 | 硬件合并 TCP 包;与 GRO 是替代关系,非串行,开启 GRO 后通常禁用 LRO |
| UFO | UDP Fragmentation Offload | 发送 | NIC | UDP 分片卸载到网卡(已于 4.14 移除) |
发送路径:
Application → TCP Stack → GSO(有 TSO 则直接卸载给网卡,否则软件分段)→ NIC
接收路径(GRO / LRO 择一):
NIC → GRO(软件合并,现代推荐)→ TCP/IP Stack → Application
NIC → LRO(硬件合并,旧方案)→ TCP/IP Stack → Application
⚠️ GRO 与 LRO 是替代关系,不是串行关系。 现代 Linux 驱动开启 GRO 后通常会自动禁用 LRO,因为 GRO 更灵活(支持转发场景,LRO 不支持)。不要同时依赖两者。
⚠️ GRO 与 tcpdump 的坑: GRO 开启时,tcpdump 抓到的可能是 64KB 超大 TCP 包。原因是 GRO 在包到达抓包点之前就已完成合并。临时关闭方法:
ethtool -K eth0 gro off,抓完再开回来。
⚠️ TSO 依赖 SG: TSO 正常工作的前提是网卡支持 Scatter-Gather I/O。若 SG 未启用,内核需先将分散内存复制为连续 buffer 才能执行 TSO,反而增加开销。排查 TSO 异常时先验证:
ethtool -k eth0 | grep scatter-gather。
二、CPU 多核扩展与负载均衡
多核服务器必备,直接决定 PPS 上限和单核瓶颈。
| 缩写 | 全称 | 类型 | 作用 |
|---|---|---|---|
| RSS | Receive Side Scaling | 硬件 | 多 RX 队列,按流哈希分发到不同 CPU |
| RPS | Receive Packet Steering | 软件 | RSS 的纯软件版,单队列网卡也能用 |
| RFS | Receive Flow Steering | 软件 | 将包调度到持有 socket 的 CPU,减少跨核竞争 |
| XPS | Transmit Packet Steering | 软件 | 发送方向 CPU 绑定,减少锁争用 |
RSS 工作原理:
NIC 收到入包
→ 按(源IP、目标IP、源端口、目标端口)计算哈希
→ 分发到不同 RX 队列
→ 各队列由独立 CPU 处理
🚧 常见现象:单核 CPU 100%,其余核空闲。 原因几乎都是 RSS 未启用或队列数为 1。检查命令:
ethtool -l eth0,预期 Combined 值大于 1。
三、校验与分片 Offload
减少 CPU 冗余计算,属于基础优化项。
⚠️ 注意: 以下缩写(CSO / RXC / TXC / LSO)并非 Linux 内核或 ethtool 的官方术语,仅用于本文的概念归类。实际
ethtool -k eth0的输出字段名为rx-checksumming、tx-checksumming等,请以工具输出为准。
| 缩写(本文) | 含义 | 作用 |
|---|---|---|
| CSO | Checksum Offload | 校验和计算整体卸载到网卡 |
| RXC | RX Checksum | 接收方向校验和由网卡验证 |
| TXC | TX Checksum | 发送方向校验和由网卡计算 |
| LSO | Large Send Offload | TSO 的早期名称,概念相同 |
查看网卡当前所有 offload 开关:
ethtool -k eth0
四、中断与轮询机制
影响高 PPS 场景下 CPU 利用率的核心机制。
| 缩写 | 全称 | 作用 |
|---|---|---|
| IRQ | Interrupt Request | 硬件中断请求,每个数据包到达时触发 |
| NAPI | New API | 中断 + 轮询混合模式,批量处理入包,减少中断次数 |
| MSI | Message Signaled Interrupt | 基于消息的中断机制 |
| MSI-X | MSI Extended | 支持多队列各自独立中断,多核场景必备 |
传统模式: 每个包 → 一次硬件中断 → CPU 处理。10M PPS 意味着每秒 1000 万次中断,CPU 直接被淹没。
NAPI 模式:
第一个包触发中断
→ 关闭中断,进入轮询
→ 批量 poll RX ring
→ 队列空后重开中断
中断次数大幅下降,CPU 效率显著提升。
五、队列与流控机制
Linux 网络栈的流量调度层。
| 缩写 | 全称 | 作用 |
|---|---|---|
| QDISC | Queue Discipline | Linux 内核队列调度框架,所有出站包都经过它 |
| BQL | Byte Queue Limits | 控制网卡驱动队列深度,防止 bufferbloat |
| TC | Traffic Control | 流量整形、限速、策略路由的用户态接口 |
常用 qdisc:默认 pfifo_fast;延迟敏感场景推荐 fq_codel;高吞吐公平调度推荐 fq。
查看当前 qdisc:
tc qdisc show dev eth0
六、现代高速网络数据路径
DDoS 防护 / 云厂商负载均衡 / eBPF 观测的核心技术。
⚠️ BPF 与 eBPF: 内核 3.18+ 后,BPF 全面扩展为 eBPF(extended BPF),具备更强的安全模型和更丰富的 hook 点。本文中 BPF 均指 eBPF,两个词在现代语境下通常可互换。
| 缩写 | 全称 | 作用 |
|---|---|---|
| XDP | eXpress Data Path | 在网卡驱动层直接处理包,可绕过内核协议栈或将包传入协议栈 |
| BPF / eBPF | Berkeley Packet Filter / extended BPF | 内核可编程过滤与观测框架 |
| AF_XDP | Address Family XDP | 用户态零拷贝高速网络接口,在内核/用户态边界工作 |
XDP 处理路径:
NIC 驱动收包
→ XDP Hook(可 DROP / PASS / REDIRECT / TX)
→ 内核网络栈
→ Socket
→ 应用
XDP 在单核上可达 10M+ PPS,而普通内核协议栈通常 1~3M PPS。Cilium、Katran(Meta LB)、Cloudflare DDoS 防护均深度依赖 XDP + eBPF 组合。
XDP vs DPDK:
| XDP | DPDK | |
|---|---|---|
| 内核绕过程度 | 驱动层拦截,可选择传入内核栈 | 完全绕过内核 |
| 使用复杂度 | 较低,与内核生态兼容 | 较高,需独占网卡 |
| 典型场景 | DDoS 防护、LB、eBPF 观测 | 高性能转发、电信 NFV |
| 性能上限 | 单核 10M+ PPS | 单核 20M+ PPS |
七、虚拟化与隧道网络
云原生、容器网络(K8s/Docker)必遇词汇。
| 缩写 | 全称 | 说明 |
|---|---|---|
| veth | Virtual Ethernet Pair | 成对出现的虚拟以太网设备,Docker/K8s 容器网络的基础原语 |
| VXLAN | Virtual Extensible LAN | L2 over UDP 隧道,云环境 Overlay 最常用 |
| GENEVE | Generic Network Virtualization Encapsulation | VXLAN 的进化版,支持可扩展元数据 |
| GRE | Generic Routing Encapsulation | 通用路由封装,三层隧道 |
| TUN | TUN 虚拟网络设备 | 三层隧道,VPN 常用 |
| TAP | TAP 虚拟网络设备 | 二层虚拟网卡,虚拟机(QEMU/KVM)常用 |
veth pair 工作原理: 每个容器的 eth0 实际上是 veth pair 的一端,另一端挂在宿主机的 bridge(如 docker0 / cni0)上。从容器发出的包从 eth0 进入 veth,直接从宿主机侧的 veth 另一端出来,无需经过完整网络栈。
八、Linux 网络性能机制层级全图
从应用层到网卡,每层对应的核心机制:
Application
↕
Socket 层
↕ ← sk_buff 贯穿以下所有层
TCP/IP 协议栈(校验和卸载:rx-checksumming / tx-checksumming)
↕
GSO / GRO 层(GSO · GRO · LRO 三选其一)
↕
QDISC / TC 层(QDISC · BQL · TC)
↕
Driver / XDP 层(XDP · BPF · NAPI · RPS · RFS · AF_XDP)
↕
NIC 硬件(SG · TSO · RSS · MSI-X)
说明: sk_buff 是内核贯穿整个网络栈的核心数据结构,从驱动层 DMA 入包到 Socket 层交付应用全程使用,不属于任何单一层。AF_XDP 是内核向用户态暴露的零拷贝套接字接口,工作在 Driver/内核边界,不是 NIC 硬件特性。
定位性能瓶颈时,从上到下逐层排查,每层有对应的工具和计数器。
九、排障必记的 16 个核心词汇
分段 / 聚合: TSO · GSO · GRO · LRO · SG
CPU 多核扩展: RSS · RPS · RFS · XPS
中断 / 队列 / 高速路径: NAPI · MSI-X · BQL · QDISC · XDP · BPF · AF_XDP
十、三个高频排障场景
场景 1:tcpdump 抓到 64KB 超大 TCP 包
根本原因: GRO 在包到达抓包点之前已合并。
# 验证
ethtool -k eth0 | grep generic-receive
# 处理(抓包期间临时关闭)
ethtool -K eth0 gro off
场景 2:单核 CPU 100%,其余核空闲
根本原因: RSS 未启用或网卡只有 1 个 RX 队列,所有包打到同一核。
# 验证(Combined 是否大于 1)
ethtool -l eth0
处理: 启用 RSS 多队列 + 配置 irqbalance 或手动绑核。
场景 3:高 PPS 时 CPU 软中断占用极高
可能原因: GRO 关闭 / NAPI budget 不足 / RPS 未配置 / MSI-X 未启用
# 验证(第 3 列 time_squeeze 持续增长则 budget 不足)
cat /proc/net/softnet_stat
处理: 调大 net.core.netdev_budget,开启 RPS,检查 MSI-X。
十一、常用排障命令速查
# 查看所有 offload 状态(含 SG / TSO / GRO / checksumming 等)
ethtool -k eth0
# 查看 / 设置队列数
ethtool -l eth0
ethtool -L eth0 combined 4
# 查看中断分布
cat /proc/interrupts
# 查看 softnet 统计(排查软中断压力)
cat /proc/net/softnet_stat
# 查看 RPS 配置
cat /sys/class/net/eth0/queues/rx-0/rps_cpus
# 查看 qdisc
tc qdisc show dev eth0
tc -s qdisc show dev eth0
完整收包路径(排障藏宝图):
NIC → DMA → RX ring → NAPI poll → GRO → IP layer → TCP → socket buffer → Application
每个节点出问题都有对应的计数器,按图索骥即可定位。
下篇预告:Linux 网络性能 30 个核心调优参数,涵盖 net.core / tcp / rmem / wmem / backlog 等关键内核参数。
基于 Linux 5.x+ 内核 · 部分特性在旧版内核上可能不完整