首页/网络/协议速查/backlog 与队列相关内核参数
TCP 与 UDP54 条

backlog 与队列相关内核参数

应用 listen(backlog) 只是「请求值」:全连接队列取 min(backlog, somaxconn),半连接队列受 tcp_max_syn_backlog;溢出行为可配 tcp_abort_on_overflow。

协议速查网络更新于 2026-10-13

两级队列与溢出行为

服务端每处理一个 SYN,内核就把连接放进两个队列:握手未完成的半连接队列,以及已完成握手、等待应用 accept 的全连接队列。应用在 listen 时给的 backlog 只是请求值,全连接队列上限取 min(backlog, net.core.somaxconn),半连接队列由 tcp_max_syn_backlog 约束。溢出时默认丢弃 ACK,客户端会先经历延迟再重传,表现为高峰期偶发连接超时。

基本信息

适用平台Linux(其他系统的参数名与行为不同)
全连接队列ss -lnt 的 Recv-Q 为当前排队数,Send-Q 为实际队列上限
溢出信号netstat -s 中 listen queue of a socket overflowed 计数持续增长
溢出策略tcp_abort_on_overflow 为 0 时丢弃 ACK 让客户端重传,为 1 时直接回 RST
半连接队列受 tcp_max_syn_backlog 与 tcp_synack_retries 影响

关键参数读法

参数作用调整建议
net.core.somaxconn全连接队列的系统上限高并发服务调到 32768 到 65535
tcp_max_syn_backlog半连接队列上限配合 somaxconn 同步调大
tcp_abort_on_overflow溢出时是否回 RST保持 0,避免业务侧看到连接被重置
tcp_synack_retriesSYN-ACK 重传次数过大延长半连接占用,过小易误判
应用 backloglisten 的请求值按并发连接数设置,不能小于业务峰值

生产常用配置

生产常用配置
# /etc/sysctl.d/99-tcp-queue.conf
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_abort_on_overflow = 0   # 0=丢 ACK 让客户端重传(客户端感知为延迟)
net.ipv4.tcp_synack_retries = 3
# 生效后核对:ss -lnt 的 Send-Q 应等于应用 backlog 与 somaxconn 的较小值

典型使用场景

  • 高峰期偶发连接超时,怀疑 accept 速度跟不上时排查队列溢出
  • 压测前统一定调 somaxconn 与应用 backlog,避免队列成为瓶颈
  • 排查 SYN 洪水:观察半连接队列与 syncookies 是否启用
  • 容器环境下确认 netns 内的参数是否需要单独设置
队列溢出的典型表现是客户端偶发连接超时,且只在高峰期出现:因为此时应用忙着处理已有连接,accept 循环跟不上,队列被填满后新连接被丢弃。
调大队列只是买时间:真正的解法是提升 accept 与业务处理速度(多进程、多线程或异步模型),否则队列越大,故障时的雪崩越晚发生但更猛烈。

易错点

  • 应用 backlog 传 128,而 somaxconn 调得再大也没用:全连接队列取两者较小值,两边都要调
  • 只看监听端口不确认生效值:改完 sysctl 需重启服务才让新 backlog 生效,ss -lnt 的 Send-Q 才是真实上限
  • 把 tcp_abort_on_overflow 设为 1:溢出时直接回 RST,客户端表现为连接被重置,反而更难判断是队列问题
  • 在容器里改了 sysctl 却以为是全局生效:部分参数是网络命名空间级别的,需要在容器或对应 netns 内设置

数据来源与参考

  • man 7 tcp(backlog 与 sysctl)
  • Linux 内核文档

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌