首页/系统/Linux 内核与性能调优速查/TCP_MAXSEG 限制单段大小
网络栈调优98 条

TCP_MAXSEG 限制单段大小

按连接设置 TCP 段长上限(MSS), 隧道或特殊链路场景可避免超出路径能力, 常规环境保持默认。

单段长度上限

TCP_MAXSEG 是套接字选项,用来限制某条连接发送的 TCP 段能承载的最大数据字节数。正常连接中这个值由双方在握手时按路径 MTU 协商,应用层很少需要干预;当隧道、VPN 或中间设备把可用载荷压小,而路径 MTU 探测又失效时,才在连接级别压小段长,让报文不超路径承载能力。它只约束发送方向,不改变对端通告的值。

基本信息

适用平台Linux(选项名在不同系统上可能不存在或语义不同)
取值单位字节,常见取值 1200 至 1400
生效时机连接建立前设置才能影响握手时通告的段长
查看方式连接的 mss 字段;抓包看首个数据段长度
相关手段路由级通告段长、全路径 MTU 探测参数

典型使用场景

  • 隧道或 VPN 链路:外层封装挤占载荷,握手协商的段长仍然偏大。
  • 中间设备丢弃 ICMP 需要分片消息,导致路径 MTU 探测失效与静默丢包。
  • 复现 MTU 相关故障:在应用侧压小段长,验证现象是否消失以确认根因方向。
  • 核对容器叠加网络中的实际段长是否符合预期。
  • 确认路径 MTU 探测是否工作,而不是长期依赖固定段长绕过。

C 用例

C 用例
int mss = 1400;   /* 按链路实际承载能力取值,不要凭感觉压到极小 */
if (setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, &mss, sizeof(mss)) < 0) {
    perror("setsockopt TCP_MAXSEG");
}

验证生效

验证生效
ss -ti 'sport = :443' | head        # 连接行中的 mss 字段即当前生效值
ip route get 203.0.113.10            # 查看该路由的 mtu 建议值
tcpdump -ni eth0 -c 5 'tcp port 443' # 观察首个数据段的实际长度是否与设置一致

三个层次的手段

层次手段适用情况
应用连接级连接选项设定段长单条连接或单进程需要限制
路由级为特定目标设置通告段长同一目标的所有连接统一限制
全栈启用路径 MTU 探测参数中间设备过滤探测报文时的补救
把段长压得过小会降低有效吞吐:每个报文的头部与中断开销占比上升,需要按链路实际承载能力取值。
分片问题与连接卡死现象的根因通常是路径 MTU,直接在应用侧限制段长只是绕过;应在确认根因后决定是否长期保留这个设置。

易错点

  • 把分片或静态丢包直接当成段长配置问题:路径 MTU 才是根因,先核实链路 MTU 与探测机制再决定是否在连接上限制。
  • 取值过小拖低有效吞吐:头部与处理开销占比上升,常见表现是延迟略降而带宽明显下降。
  • 在连接建立之后才设置:握手已按协商值完成,设置只影响后续发送,实测与预期不符。
  • 只改一端:对端通告的段长仍然偏大,反方向的问题不会消失。
  • 读值当作自己设置过的值:读取返回的是当前生效值,与设置不一致时以抓包实测为准。

数据来源与参考

  • man 7 tcp
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌