汇知百科
白蓝主题五 · 清爽阅读
首页  > 故障排查

协议栈连接数优化实战指南

连接数上不去?先看系统瓶颈在哪

线上服务突然响应变慢,监控显示新建连接数卡在几千上不去,重启服务只能撑十分钟。这种情况别急着改代码,大概率是协议层面的连接数没调好。

Linux 默认的连接限制偏保守,一个普通云服务器刚起来时,能同时处理的 TCP 连接通常不超过 3 万。对于网关、长连接服务或者高并发 API,这数字根本不够用。

检查当前连接状态

先用 netstat 或 ss 看看真实情况:

ss -s

输出里会显示当前 ESTAB(已建立)、TIME-WAIT、SYN-RECV 的数量。如果 SYN 队列堆积严重,说明握手阶段就卡住了。

调整内核参数是关键

打开 /etc/sysctl.conf,加几行硬货:

net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15

这几条分别管的是:最大监听队列、网卡收包队列、SYN 队列深度、本地端口范围、TIME-WAIT 复用和 FIN 超时时间。改完执行 sysctl -p 生效。

别忘了文件描述符限制

每个 TCP 连接都占一个 fd,系统默认 ulimit -n 可能只有 1024。服务跑起来没多久就报 "Too many open files"。

编辑 /etc/security/limits.conf,给运行用户加上:

* soft nofile 65536
* hard nofile 65536

如果是 systemd 启动的服务,还得在 service 文件里加 LimitNOFILE=65536,不然不生效。

应用层也要配合

Java 服务用 Netty 做通信框架时,默认 backlog 是 128。就算系统调再高也没用。得显式设置:

ServerBootstrap b = new ServerBootstrap();
b.option(ChannelOption.SO_BACKLOG, 65535);

Node.js 也一样,listen 的第二个参数就是 backlog,不设就是系统默认值,可能远低于你调的 somaxconn。

压测验证才敢上线

改完别直接扔生产。用 wrk 或者 jmeter 模拟高并发连接,观察是否还会出现连接超时或拒绝。

比如用 wrk 打接口:

wrk -t12 -c4000 -d30s http://your-api.com/health

逐步加压,看到 RPS 稳定、延迟不飙升才算真正撑住了。

某次我们调了一个 MQTT 接入层,从最初撑不住 8000 连接,到最后单机扛下 12 万长连接,核心就是上面这几步一步步摸出来的。系统资源够,协议栈不拖后腿,服务才能放开跑。