TCP 的 MSS 和 MTU 有什么区别?为什么会影响传输性能?
简化版
MTU 是链路层一次能承载的最大 IP 包大小,MSS 是 TCP 单个报文段最多承载的应用数据大小。以以太网 MTU 1500 为例,IPv4 头 20 字节、TCP 头 20 字节时,常见 MSS 是 1500 - 20 - 20 = 1460 字节。
详细版
MSS 和 MTU 的关系可以这样讲:
- MTU 面向 IP 包大小,受链路限制,比如以太网常见 1500 字节。
- MSS 面向 TCP 载荷大小,是 TCP 数据部分的上限。
- 常见 IPv4 无选项场景:
MSS = MTU - IP头 - TCP头 = 1500 - 20 - 20 = 1460。 - MSS 常在 TCP 三次握手的选项里协商,双方告诉对方自己可接收的最大段大小。
- 如果包超过路径 MTU,可能发生 IP 分片;若设置 DF 且路径不支持这么大的包,会依赖 PMTUD 发现可用 MTU。
面试重点是:MSS 是为了让 TCP 尽量避免 IP 分片,分片会增加丢包和重传成本。
完整版教学
一、先分清 MTU 和 MSS 属于哪一层
MTU 是 Maximum Transmission Unit,描述某条链路一次能承载的最大网络层数据包大小。MSS 是 Maximum Segment Size,描述 TCP 报文段里应用数据部分的最大长度。两者相关,但不是同一个概念。
以太网帧
└── IP 包 <= MTU
├── IP 头
└── TCP 段
├── TCP 头
└── TCP 数据 <= MSS
常见以太网 MTU 是 1500 字节。IPv4 头无选项通常 20 字节,TCP 头无选项通常 20 字节,所以常见 MSS 是 1460 字节。
记忆钩子:MTU 管“整只 IP 包能多大”,MSS 管“TCP 数据能装多少”。
二、为什么 MSS 要在握手时协商
TCP 连接的两端可能处在不同网络环境里,接收能力也不同。MSS 选项通常在 SYN 报文中出现,用来告诉对端“你发给我的 TCP 数据段不要超过这个大小”。
如果客户端通告 MSS 1460,服务端发送数据时会尽量把单段 TCP payload 控制在 1460 以内。这样 IP 包加上头部后不超过常见路径 MTU,降低分片概率。
| 项目 | 作用对象 | 常见值 | 出现场景 |
|---|---|---|---|
| MTU | IP 包总大小 | 1500 | 链路或接口配置 |
| MSS | TCP 数据大小 | 1460 | TCP SYN 选项 |
| IP 头 | 网络层头部 | 20 字节 | IPv4 无选项 |
| TCP 头 | 传输层头部 | 20 字节 | TCP 无选项 |
注意 TCP 选项会让 TCP 头超过 20 字节,但 MSS 值本身表达的是最大数据载荷,不是 TCP 包总长。
三、分片为什么影响性能和可靠性
如果一个 IP 包超过某段链路 MTU,IPv4 可能分片。分片的问题是:任意一个分片丢失,整个原始 IP 包都无法重组成功。对 TCP 来说,这通常表现为整个 TCP 段丢失,需要重传。
原始 IP 包 4000 字节,路径 MTU 1500:
分片1 1500
分片2 1500
分片3 约1000
只要分片2丢失,整个 4000 字节 IP 包都失败
分片还会增加路由器、接收端重组、故障排查成本。现代网络通常尽量通过 MSS 控制和路径 MTU 发现避免分片,而不是依赖分片解决问题。
四、PMTUD 和 DF 位解决什么问题
路径 MTU 不是只看本机网卡,因为中间链路可能更小。PMTUD 的目标是发现从源到目的地整条路径上可用的最小 MTU。典型做法是发送设置 DF 位的包,如果中间设备发现包太大且不能分片,就返回 ICMP 提示。
Host A -- MTU 1500 -- Router -- MTU 1400 -- Host B
如果 A 发 1500 且 DF=1:
Router 发现下一跳只能 1400
-> 丢弃并返回 ICMP Fragmentation Needed
-> A 降低报文大小
如果 ICMP 被错误拦截,就可能出现“PMTUD 黑洞”:小包能通,大包卡住。这类问题在线上很隐蔽,常表现为连接能建、少量数据能发、大响应或上传失败。
五、MSS、TCP 选项和隧道开销
VPN、GRE、IPsec、容器网络、云厂商隧道都会额外加头,导致有效 MTU 变小。如果仍按 1500/1460 发送,进入隧道后包可能超过底层路径 MTU。
举例:底层 MTU 1500,隧道额外开销 50 字节,那么内部可用 IP 包最好不超过 1450。对应 IPv4/TCP 无选项 MSS 大约是:
effective_mss = 1500 - 50 - 20 - 20 = 1410
这就是为什么跨云、容器、VPN 场景经常需要调整 MTU 或做 MSS clamping。它不是玄学优化,而是在避免路径中间产生分片或黑洞。
六、面试和排障怎么组织答案
答题时不要只背 1460,要把链路层限制、IP 包、TCP 数据、分片代价串起来。排障时可以从“是否大包失败”入手:ping 小包通、大包不通;TLS 握手后大响应卡住;上传文件中断;跨 VPN 调用异常。
| 现象 | 可能原因 | 处理方向 |
|---|---|---|
| 小请求成功,大响应卡住 | PMTUD 黑洞 | 放通 ICMP、降低 MSS |
| VPN 内访问不稳定 | 隧道开销导致 MTU 变小 | 调整接口 MTU 或 MSS clamping |
| 抓包看到 IP fragments | 发生分片 | 降低包大小,检查路径 MTU |
| 重传率高 | 分片丢失或链路质量差 | 看分片、MTU、丢包位置 |
七、常见误区与追问
- 误区:MSS 就等于 MTU。 MSS 只算 TCP 数据,MTU 算整个 IP 包,两者差了 IP/TCP 头部。
- 误区:以太网 MTU 1500 时 MSS 永远是 1460。 IPv6、TCP 选项、隧道封装都会改变可用空间。
- 误区:分片只是多拆几个包,没什么影响。 任意分片丢失会导致原包失败,还会增加重组和排查成本。
- 追问:MSS 在哪里协商? 常见在 TCP 三次握手的 SYN 选项中通告给对方。
- 追问:PMTUD 黑洞是什么? 包太大且 DF 置位,中间需要 ICMP 通知变小,但 ICMP 被拦截,导致大包一直失败。
- 追问:为什么隧道场景要调 MSS? 隧道额外头部占空间,有效 MTU 变小,MSS 不降就可能超路径 MTU。
八、加强记忆
MSS/MTU 按“外壳和载荷”记:MTU 是 IP 包外壳上限,MSS 是 TCP 数据载荷上限。经典数字 1500 - 20 - 20 = 1460 只是 IPv4 无选项以太网场景,遇到 IPv6、TCP 选项、VPN、容器网络时要重新扣头部开销。