关闭 Nagle 算法
Nagle 算法会把小块数据攒起来,等前一个报文被确认后再发送,用来减少小包数量。对请求响应型连接,这个等待会与对端的延迟确认叠加,产生规律性的额外往返。TCP_NODELAY 关闭该算法,让每次写操作尽可能立即发出。它适合小请求频繁往返的连接,不适合大流量批量传输。
基本信息
| 适用平台 | Linux / Unix,其它系统同样提供同名选项 |
|---|---|
| 取值 | 1 关闭 Nagle 立即发送,0 使用默认算法 |
| 默认状态 | 启用 Nagle |
| 适用画像 | 小请求响应型、往返次数多、单次数据小 |
| 副作用 | 小包数量上升,头部与处理开销占比提高 |
典型使用场景
- 远程调用与数据库客户端:命令与结果都是小数据,往返延迟敏感。
- 长连接上的小响应服务,需要压低尾部延迟。
- 排查规律性的固定量级延迟尖刺,判断是否由攒包与延迟确认叠加造成。
- 压测中验证关闭算法的收益,避免只凭经验一刀切。
- 反例场景:大文件与批量数据传输,通常不需要且不划算。
C 用例
C 用例
int one = 1;
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) < 0) {
perror("setsockopt TCP_NODELAY");
}
/* 逐连接按业务特征设置,比全局一律开启更容易评估效果 */量化对比
量化对比
ss -tin state established 'sport = :8080' | head # 看往返时间与确认超时相关字段
tcpdump -ni eth0 -c 50 'tcp port 8080' # 观察相邻报文间隔与包长分布
sar -n DEV 1 5 # 对比开启前后的包速率变化按连接类型取舍
| 连接特征 | 是否关闭算法 | 理由 |
|---|---|---|
| 小请求高频往返 | 建议关闭 | 减少等待确认造成的额外往返 |
| 大块顺序传输 | 不建议 | 攒包带来的开销节省更有价值 |
| 混合负载 | 按连接区分 | 一刀切会让两类流量互相拖累 |
应用层合并写请求往往比全局关闭 Nagle 更有效:减少写调用次数从根源上减少小包,且不影响其它连接。
对全部连接一律关闭会明显抬高包量与 CPU 占用;建议先在少量连接上验证,用同一负载对比包速率与延迟分布再推广。