网络栈调优98 条

监听队列溢出诊断

客户端报连接超时、服务日志出现握手失败时,用溢出计数与 ss 队列读数区分 SYN 队列满还是 accept 队列满,再决定调参数或改应用。

队列溢出是怎么发生的

TCP 握手过程中连接在内核里排队等待应用 accept,队列分两段:SYN 队列(半连接,收到 SYN 尚未完成握手)与 accept 队列(已完成握手等待应用取走)。两段各有上限,超限时内核按策略丢弃:SYN 队列满可启用 SYN cookies 兜底;accept 队列满时默认丢弃最终 ACK,客户端表现为连接超时并重试。诊断第一步就是分清是哪一段在溢出。

基本信息

SYN 队列上限net.ipv4.tcp_max_syn_backlog
accept 队列上限应用 listen 的 backlog 与 net.core.somaxconn 取较小值
溢出计数netstat -s 的 listen queue of a socket overflowed、SYN cookies sent
队列直读ss -lnt 的 Recv-Q(已握手待 accept)与 Send-Q(当前上限)
溢出行为net.ipv4.tcp_abort_on_overflow=0 丢 ACK 让对端重试,为 1 则直接 RST

典型使用场景

  • 客户端间歇性连接超时、重试后又成功,疑似队列溢出
  • 发布或秒杀瞬间连接大量涌入,短时排队超过上限
  • 应用 accept 或首包处理偏慢,瓶颈在应用侧而非网络侧
  • 调参前后验证:改完 backlog 与 somaxconn 看溢出计数是否还在增长
  • 容量评估:区分应用处理能力不足还是排队容量不足

看计数与队列

看计数与队列
netstat -s | grep -iE 'overflow|listen|syn cookie'   # 累计溢出与 SYN cookies 计数
ss -lnt                                               # Recv-Q 逼近 Send-Q 即 accept 跟不上
ss -s                                                 # 全局连接状态汇总
sysctl net.core.somaxconn net.ipv4.tcp_max_syn_backlog net.ipv4.tcp_abort_on_overflow
sysctl -w net.core.somaxconn=4096                     # 抬高 accept 队列硬上限
netstat -s | grep -c 'listen queue'                    # 采样两次做差值才有意义

字段逐列读法

字段含义异常表现
Recv-Q(LISTEN)已完成握手、等待 accept 的连接数持续贴近 Send-Q 说明应用取连接太慢
Send-Q(LISTEN)该监听套接字当前的 accept 队列上限等于 backlog 与 somaxconn 的较小值
listen queue overflowedaccept 队列满导致丢弃的累计次数持续增长即为真实溢出
SYN cookies sent半连接队列满时用 cookies 兜底应答的次数大量增长说明 SYN 队列被打满,疑似泛洪
tcp_abort_on_overflow0 丢 ACK 让客户端重试,1 立即回 RST为 1 时客户端报连接被重置
这些都是累计计数,必须比较两次采样的差值;单次读数无法判断溢出是否仍在发生。
accept 队列的真实上限取应用 listen(backlog) 与 somaxconn 的较小值,只调 sysctl 不改应用参数等于没调。
溢出多半是应用 accept 慢或处理慢的结果而非根因;调大队列只是争取缓冲,积压点会从内核队列转移到应用内部。

易错点

  • 只看一次 netstat -s 的累计数字就判断正在溢出:必须比较采样差值
  • 把队列调大当成修复:应用处理能力不变,只是把积压从内核挪到应用内部
  • 只调 somaxconn 不改应用 backlog:两者取小值,改了也可能不生效
  • 混淆两段队列:SYN cookies 增长指向半连接队列,overflow 计数指向 accept 队列
  • 把 tcp_abort_on_overflow 改成 1 而不评估:会直接 RST 客户端连接,把超时放大成报错

数据来源与参考

  • man ss
  • Linux Documentation/networking/ip-sysctl.txt
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌