温馨提示×

怎样优化linux backlog

小樊
34
2026-09-05 12:08:09
栏目: 智能运维

在 Linux 中,backlog 通常出现在两个层面:

  1. TCP 监听队列(listen backlog)
  2. 内核网络/系统相关队列(如半连接、全连接队列)

下面从原理 → 查看 → 优化三个层面说明。


一、理解 Linux 中的 backlog

1. TCP listen backlog 是什么

listen(fd, backlog);

backlog 表示 已完成三次握手、等待 accept 的 socket 数量上限(全连接队列)。

⚠️ 实际队列长度 ≠ backlog
实际值 = min(backlog, net.core.somaxconn)


2. 两个关键队列

队列 说明 对应参数
半连接队列 SYN 已收到,未完成握手 net.ipv4.tcp_max_syn_backlog
全连接队列 已完成握手,等待 accept net.core.somaxconn + listen(backlog)

二、查看当前状态

1. 查看系统参数

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

2. 查看监听队列是否溢出

ss -lnt

示例:

State  Recv-Q Send-Q Local Address:Port
LISTEN 0      128    :::80
  • Send-Q = 当前 backlog 上限
  • Recv-Q 接近 Send-Q,说明队列快满了

3. 查看溢出统计

netstat -s | grep -i listen

nstat | grep -i listen

关注:

  • ListenOverflows
  • ListenDrops

三、优化方法

✅ 1. 增大系统级 backlog(最关键)

# 临时
sysctl -w net.core.somaxconn=65535
sysctl -w net.ipv4.tcp_max_syn_backlog=65535

# 永久
vim /etc/sysctl.conf
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
sysctl -p

✅ 2. 应用代码中正确设置 backlog

很多程序默认 backlog 很小(如 128、511)

Nginx

listen 80 backlog=65535;

Redis

tcp-backlog 65535

Java

serverSocket.bind(new InetSocketAddress(port), 65535);

Go

net.ListenConfig{}.Listen(ctx, "tcp", addr)
// 依赖系统 somaxconn

✅ 3. 加快 accept 速度(更重要)

backlog 再大,如果:

  • 业务处理慢
  • 单线程 accept
  • 锁竞争严重

都会堆满队列。

优化方向:

  • 多线程 / 多进程 accept
  • 使用 SO_REUSEPORT
  • 异步 IO(epoll / io_uring)

✅ 4. 调整 TCP 握手相关参数(高并发场景)

net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15

四、常见误区

❌ 只改 listen(backlog) 不生效
✅ 必须同时调 somaxconn

❌ backlog 越大越好
✅ 队列只是缓冲,处理能力才是根本

❌ 忽略 accept 性能
✅ 队列满了仍然会丢连接


五、典型推荐配置(高并发服务器)

net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_syncookies = 1

应用 backlog ≥ 1024(建议 65535)


如果你能告诉我:

  • 使用的语言/框架(Nginx / Java / Go / Redis)
  • 短连接还是长连接
  • 当前 ListenOverflows 是否增长

我可以给你更精确的优化方案。

0