单机websocket连接数卡在1k–5k,主因是文件描述符限制、nf_conntrack_max容量、tcp内核参数未调优;需同步修改ulimit、/etc/security/limits.conf、systemd limitnofile、nf_conntrack_max及net.core.somaxconn等参数。

单机 WebSocket 连接数卡在 1k–5k,不是代码写得差,而是三个地方没调:文件描述符限制、连接跟踪表容量、TCP 内核参数。改完这三处,10 万+ 是常态,百万级也跑得起来。
ulimit -n 不生效?检查 limits.conf 和启动上下文
每个 WebSocket 连接至少占 1 个 fd,Linux 默认 ulimit -n 是 1024 —— 新连接直接被拒绝,日志里常出现 Too many open files 或静默丢包。
- 临时生效必须在启动服务的同一 shell 中执行:
ulimit -n 65535(对node、php、go进程都有效) - 永久生效要改
/etc/security/limits.conf,且必须包含两行:* soft nofile 1048576和* hard nofile 1048576 - 如果用
systemd启动(比如nginx、workerman),还得在 service 文件里加LimitNOFILE=1048576,否则 limits.conf 不起作用 - 验证是否生效:
cat /proc/$(pgrep -f 'your_server_cmd')/limits | grep "Max open files"
nf_conntrack_max 满了会导致连接秒断
当连接数上万后,突然出现客户端 ping 不通、握手成功但发几条消息就断开,且日志无明显报错 —— 很可能触发了 nf_conntrack: table full, dropping packet。
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
- 默认值通常只有 65536,远不够支撑 10 万+ 连接
- 临时改:直接写入
echo 2621440 > /proc/sys/net/netfilter/nf_conntrack_max - 永久改:在
/etc/sysctl.conf加一行net.netfilter.nf_conntrack_max = 2621440,再运行sysctl -p - 注意:这个值不能无上限设,建议控制在物理内存的 1GB/10 万连接范围内(每条 conntrack 记录约占用 300–400 字节)
net.core.somaxconn 和 tcp_tw_reuse 必须配齐
net.core.somaxconn 控制 accept 队列长度,tcp_tw_reuse 决定 TIME-WAIT 端口能否复用 —— 这两个参数不调,高并发下会出现 listen backlog 满、新连接进不来、或端口耗尽。
- 把
net.core.somaxconn设为65535(不能只改应用层 backlog,内核队列才是瓶颈) - 启用
net.ipv4.tcp_tw_reuse = 1,避免短连接密集场景下端口被锁死 - 顺手调大端口范围:
net.ipv4.ip_local_port_range = 1024 65535(尤其对 Nginx 代理场景,它自己也要消耗本地端口) - 别漏掉
net.ipv4.tcp_max_syn_backlog = 65536,这是 SYN 半连接队列,防止洪水攻击式握手打满队列
Nginx 代理时,端口四元组才是真实上限
很多人以为调完系统参数就能无限连,结果发现 Nginx 后面的 WebSocket 服务最多撑到 6w 左右就上不去 —— 因为 Nginx 自身作为 client 去连后端,每条连接要占一个本地端口,而 ip_local_port_range 最大可用端口就是 ~65535。
- 单台 Nginx + 单台后端服务器,理论硬上限 ≈
65535(减去系统保留端口) - 突破方法只有两个:横向扩 Nginx 实例(不同 IP 或不同 local_port 范围),或者让 Nginx 复用连接(需后端支持 HTTP/1.1 keepalive + connection pooling)
- 若不用 Nginx,直接暴露 WebSocket 服务(如 uWebSockets、gobwas/ws),则只受限于服务端本机资源和
nf_conntrack_max
真正卡住百万连接的,往往不是代码逻辑,而是 nf_conntrack_max 没调、ulimit 在 systemd 下失效、或 Nginx 端口耗尽却误以为是服务端问题 —— 这三处最容易被跳过检查。










