Nagle 算法(发送端):只要还有未确认的数据在途,新的小段数据就先缓存不发送,攒到 MSS 大小或收到 ACK 再发——目的是减少网络中的小包数量,提高带宽利用率。延迟确认(接收端):收到数据后不立即回 ACK,等待最多 200ms(Linux 典型 40ms),期望捎带在即将发送的响应数据上,减少纯 ACK 包。
二者叠加会产生经典的 40~200ms 卡顿:发送方的小包被 Nagle 攒住等 ACK,接收方的 ACK 被延迟确认攒住等数据,互相等待直到定时器超时——写-写-读模式的应用(先写请求头再写请求体再读响应)特别容易踩中。解决方案:交互式/低延迟应用在发送端设置 TCP_NODELAY 禁用 Nagle(SSH、Redis、游戏、RPC 框架的标配);或者把多次小写合并成一次 writev/批量发送,从应用侧规避。接收端可用 TCP_QUICKACK 临时禁用延迟确认。追问方向:Nagle 与 TCP_CORK 的区别(CORK 是主动攒够再发,不等 ACK)、为什么 HTTP/1.1 的头部和体部分两次 send 会触发此问题。
(约 420 字)