温馨提示×

什么程序占用linux backlog

小樊
43
2026-10-08 07:31:36
栏目: 智能运维

在 Linux 网络编程里,backlog 通常指的是 listen() 系统调用中的 backlog 参数,以及内核中对应的 连接队列(accept queue / syn queue)。下面从“什么程序/场景会占用 backlog”和“如何排查”两方面说明。


一、backlog 是什么(先澄清概念)

int listen(int sockfd, int backlog);
  • backlog 定义的是:已完成连接(ESTABLISHED)但还没被 accept() 取走的队列长度上限
  • 实际受两个内核参数影响:
    • net.core.somaxconn(默认常是 128 / 4096)
    • net.ipv4.tcp_max_syn_backlog(半连接队列)

注意:老教材说 backlog 包含半连接,但现代 Linux 中 半连接和全连接是分开的。


二、哪些“程序”会占用 backlog

任何调用了 listen() 的服务端程序都会占用 backlog,典型包括:

1. 网络服务程序(最常见)

  • Web 服务器
    • Nginx
    • Apache
    • Tomcat
  • 中间件
    • Redis
    • MySQL
    • Kafka
    • RabbitMQ
  • 自研服务
    • 用 C / Go / Java / Python 写的 TCP 服务

只要:

client 连上 → 三次握手完成 → 程序没及时 accept()

backlog 就会被占用。


2. 程序“占着 backlog 不消费”的典型原因

这些程序表面上在跑,但实际在占 backlog:

  • accept() 调用太慢
    • 单线程模型
    • 业务逻辑阻塞(锁、IO、DB)
  • worker 进程/线程不够
    • Nginx worker 太少
    • Java 线程池满
  • 程序卡死 / GC 停顿
    • Java Full GC
    • 死锁
  • 突发流量超过处理能力
    • 秒杀、压测、攻击

3. 客户端不算“占用 backlog”

  • 客户端 connect() 只是发起连接
  • 真正占用 accept queue 的是:
    • 服务端 listen socket + 未 accept 的连接

三、如何看“谁占用了 backlog”

1. 看连接队列是否满

ss -lnt

关注:

Recv-Q   Send-Q
  • Recv-Q:当前 accept 队列中 未 accept 的连接数
  • Send-Q:该 socket 的 backlog 上限

示例:

LISTEN 100 128 0.0.0.0:80

→ 已占 100,上限 128(快满了)


2. 看具体端口被谁占用

lsof -i :80
ps -ef | grep nginx

3. 看半连接队列(SYN 占用)

netstat -an | grep SYN_RECV | wc -l

4. 内核参数

sysctl net.core.somaxconn
sysctl net.ipv4.tcp_max_syn_backlog

四、常见误区分点

❌ “backlog 是客户端占的”
✅ 是 服务端 listen socket 的队列

❌ “backlog 越大越好”
✅ 太大可能掩盖程序性能问题

❌ “连接断了就立刻释放”
✅ 若程序不 accept,连接会一直占着


五、一句话总结

所有调用 listen() 的服务端程序都会占用 Linux backlog;当程序处理慢、线程少或流量突增时,backlog 会被“已连接但未被 accept”的 socket 占满。

如果你愿意,可以告诉我:

  • 你用的是 Nginx / Java / Go / 某个服务
  • 或者贴出 ss -lnt 的输出
    我可以帮你精准判断是谁在占、怎么优化。

0 踩