3. 链路层与物理层性能影响
TCP/IP 的性能问题经常被归因于传输层或应用层,但真正决定“每一跳能搬多少数据、搬得稳不稳”的,往往是链路层与物理层。本节围绕五个关键因素展开:MTU、MSS、链路误码、双工模式、网卡卸载。它们分别作用于分片、分段、丢包、冲突与 CPU 开销,理解其作用位置,才能判断性能瓶颈究竟出在哪一层。
MTU 与 MSS:一个管“帧”,一个管“段”
MTU(Maximum Transmission Unit)是链路层单个帧能承载的最大数据载荷,以太网默认 1500 字节。MSS(Maximum Segment Size)是 TCP 层单个报文段能承载的最大数据量,它由双方在三次握手时通过 MSS 选项协商,通常取“路径 MTU 减去 IP 头(20)和 TCP 头(20)”,即 1500−40=1460 字节。二者关系可以概括为:MTU 限制的是帧,MSS 限制的是段,MSS 必须让“段+IP头+TCP头”不超过路径 MTU。
如果 MSS 设置过大,超过路径 MTU,IP 层就会分片。分片会带来两个代价:一是任一分片丢失,整个报文都要重传;二是分片重组消耗接收端内存与 CPU。因此现代网络更推荐路径 MTU 发现(PMTUD),由发送方发送 DF=1 的探测包,若中间链路返回 ICMP“需要分片”,则下调 MSS。若 ICMP 被防火墙拦截,就会出现“小包通、大包不通”的典型黑洞现象。
实际调优时,可用如下命令确认路径 MTU 与当前接口 MTU:
# 查看接口 MTU
ip link show eth0 | grep mtu
# 探测路径 MTU(Linux,DF 置位,包长 1472 + 28 头 = 1500)
ping -M do -s 1472 10.0.0.1
# 查看 TCP 实际 MSS
ss -i | grep -E "mss|rtt"
若探测 1472 字节失败而 1400 字节成功,说明路径 MTU 小于 1500,应把接口或隧道 MTU 下调到对应值,并同步调整 MSS clamp,避免分片。
链路误码:为什么“带宽够”却“跑不快”
链路误码指物理介质上比特传输出错的概率,常用 BER(误码率)衡量。铜缆、光纤、无线、电力线等介质的 BER 差异很大。误码对 TCP 的伤害不是线性的:一个比特错误若落在报文段内,会触发校验和失败,接收端丢弃该段,发送端只能靠超时或快速重传恢复。在长肥管道(高带宽时延积)中,一次丢包就可能让拥塞窗口减半,吞吐量骤降。
判断误码是否成为瓶颈,可观察接口统计中的 CRC 错误、帧对齐错误、丢弃计数:
ip -s link show eth0
# 关注 RX errors、CRC、frame、dropped 是否持续增长
ethtool -S eth0 | grep -Ei "crc|error|drop"
若 CRC 错误随流量增长而增长,优先排查网线质量、光模块、接头与电磁干扰,而不是先调 TCP 参数。无线场景中,误码还与信号强度、重传次数相关,应结合 RSSI 与重传率综合判断。
双工模式:半双工是隐藏的吞吐杀手
双工模式决定链路能否同时收发。全双工下收发独立,无冲突;半双工下同一时刻只能一个方向发送,需要 CSMA/CD 竞争,冲突会导致退避与重传。更隐蔽的问题是“双工不匹配”:一端强制全双工,另一端自协商为半双工,结果全双工端持续发送,半双工端检测到冲突并丢弃,表现为延迟抖动、丢包和吞吐下降,而带宽利用率看起来并不高。
排查时应确认两端协商结果一致:
ethtool eth0 | grep -E "Speed|Duplex|Auto"
# 期望:Speed: 1000Mb/s,Duplex: Full,Auto-negotiation: on
若出现 Half 或速率降级,应检查网线类别(千兆需 Cat5e 以上)、端口配置与光模块兼容性。原则是:两端尽量都设为自协商,避免一端强制、一端自动。
网卡卸载:把 CPU 从协议栈里解放出来
网卡卸载(offload)把校验和计算、分段、聚合等任务下移到网卡硬件,减少主机 CPU 开销。常见能力包括:
- TSO/GSO:发送端大段分段,网卡按 MSS 切分,降低协议栈分段次数;
- LRO/GRO:接收端把小包聚合成大包再交给协议栈,减少中断与处理次数;
- 校验和卸载:由网卡计算 IP/TCP/UDP 校验和;
- RSS:多队列把不同流散列到不同 CPU 核,提升并行处理能力。
卸载并非越多越好。在虚拟化、容器或抓包场景中,TSO/LRO 会让抓到的包与实际线缆上的包不一致,影响分析;某些驱动或虚拟交换机组合下,卸载还可能引入异常。可用如下命令查看与调整:
ethtool -k eth0 | grep -E "tso|gso|gro|lro|rx-checksum"
ethtool -K eth0 tso off gro off # 排障时临时关闭
ethtool -L eth0 combined 8 # 调整 RSS 队列数
判断卸载是否生效,可对比开启与关闭时的 CPU 软中断占比(mpstat -P ALL 1 看 %soft)与吞吐。若关闭卸载后吞吐明显下降、CPU 升高,说明卸载确实在分担负载;若关闭后问题消失,则说明该卸载路径存在兼容性缺陷。
把五个因素串成一条排查路径
面对“带宽够但吞吐低”的问题,建议按“物理层→链路层→传输层→主机”的顺序排查。先看 ip -s link 与 ethtool -S 是否有 CRC、frame、drop 持续增长,确认误码与双工;再用 ping -M do 探测路径 MTU,确认是否存在分片或 PMTUD 黑洞;接着用 ss -i 观察 MSS、重传与 cwnd;最后用 ethtool -k 与 mpstat 评估卸载与 CPU 软中断。这个顺序的价值在于:物理层问题无法靠调 TCP 参数解决,而卸载配置错误又常被误判为“网络慢”。
ping -M do 验证。综上,MTU 与 MSS 决定“包能不能顺利通过”,链路误码与双工决定“链路稳不稳”,网卡卸载决定“主机扛不扛得住”。把这五个因素放在同一条作用链上理解,才能把 TCP/IP 性能优化从“调参数”变成“定位瓶颈”。