首页/系统/Linux 内核与性能调优速查/TCP_QUICKACK 立即确认模式
网络栈调优98 条

TCP_QUICKACK 立即确认模式

对延迟敏感的请求响应型连接, 可开启立即确认减少等待; 默认延迟确认是为批量吞吐设计。

立即确认模式

TCP 默认使用延迟确认:收到数据后并不马上回 ACK,而是等待一小段时间以合并确认、减少包量。对请求响应型的小交互,这段等待会让每次往返多出毫秒级延迟。TCP_QUICKACK 用来让内核对本连接立即发送确认。它不是一个持久开关:部分内核会在后续收包后把状态重置,需要按交互节奏重新设置。

基本信息

适用平台Linux(同名选项来源为 Linux 扩展)
取值1 使用立即确认,0 恢复默认延迟确认
默认状态延迟确认,等待时间受本端确认超时定时器影响
持久性非持久,内核可能重置,需重复设置
搭配与 Nagle 关闭策略一起评估

典型使用场景

  • 小请求响应型服务出现固定量级的延迟尖刺,怀疑与延迟确认叠加有关。
  • 数据库或缓存客户端在单连接上与固定延迟叠加相关的问题定位。
  • 压测中需要验证瓶颈到底在确认等待还是在应用处理。
  • 长连接上偶发的慢请求归因,排除是否由确认定时器造成。
  • 确认 Nagle 关闭后延迟是否仍然存在,以判断还要不要处理确认侧。

C 用例

C 用例
int one = 1;
if (setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one)) < 0) {
    perror("setsockopt TCP_QUICKACK");
}
/* 该状态可能被内核重置,关键交互之后需要重新设置 */

确认瓶颈位置

确认瓶颈位置
ss -ti 'sport = :3306' | head     # 观察 rtt 与确认超时相关字段
ss -tin state established 'sport = :3306'   # 不解析服务名,便于脚本化
tcpdump -ni eth0 -ttt 'tcp port 3306' -c 20 # 看连续报文之间的时间间隔是否成固定量级
strace -c -p 12345 -f                 # 看应用读写次数,排除应用侧逐次小写

现象与处置

观察到的现象可能原因处置方向
延迟成固定量级且很有规律延迟确认与 Nagle 叠加先合并写,再评估立即确认
包量上升、延迟略降立即确认的代价显现评估是否只对关键连接开启
延迟无规律、波动大多半不是确认侧问题转向锁、IO 与调度方向排查
延迟确认与 Nagle 要一起评估:先抓包确认瓶颈是确认等待还是发送侧攒包,再决定改哪一侧。
在吞吐型连接上强制立即确认会增加包量与处理开销,通常得不偿失;改动前用压测对比整体指标,而不是只看单次请求延迟。

易错点

  • 在吞吐型连接上强制立即确认:确认包数量上升,内核与网卡处理开销增加,整体吞吐可能反而下降。
  • 把它当持久开关:部分内核在后续收包后重置状态,效果消失后误判为「选项无效」。
  • 不看对端与 Nagle 的状态就下结论:两者叠加才产生规律性的固定延迟,只改一侧往往看不到改善。
  • 忽略应用层写合并:逐字节写造成的性能问题,用确认策略掩盖只会把开销转移到网络上。
  • 在生产全量开启后才做验证:缺少改动前后的同一负载对比,无法判断收益是否真实。

数据来源与参考

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