单机websocket连接数卡在1k–5k,主因是ulimit -n、net.core.somaxconn、nf_conntrack_max三参数未调优;需分别设为≥1048576、65535、1048576,并配套调整tcp_max_syn_backlog、ip_local_port_range等。

单机 WebSocket 连接数卡在 1k–5k,不是代码写得差,而是 ulimit -n 没调、net.core.somaxconn 没改、nf_conntrack_max 没扩——这三个系统参数任一遗漏,65535 就只是个数字。
Linux 文件描述符必须改到 100 万级
每个 WebSocket 连接至少占用 1 个文件描述符(fd),而默认 ulimit -n 是 1024。新连接会直接被内核拒绝,日志里常见 Too many open files 或静默丢包。
- 临时生效:在启动服务前的同一 shell 中执行
ulimit -n 1048576 - 永久生效:向
/etc/security/limits.conf追加两行:* soft nofile 1048576和* hard nofile 1048576,并确认服务进程由该用户启动(如 Nginx worker、GoAccess、Node.js) - Go 程序需在
net.Listen前主动调用syscall.Setrlimit,否则 runtime 不会自动申请软限制上限 - Docker 容器要额外加
--ulimit nofile=1048576:1048576,否则Setrlimit会被权限拒绝
内核网络参数不调,listen 队列就永远堵死
net.core.somaxconn 控制 accept() 队列长度,低于并发连接数时,握手完成的连接进不了队列,客户端表现为“连不上”或超时。
本文档主要讲述的是Android 操作系统的介绍;Android是基于Linux内核的操作系统,是Google公司在2007年11月5日公布的手机操作系统,早期由Google开发,后由开放手持设备联盟(Open Handset Alliance)开发。它采用了软件堆层(software stack,又名以软件叠层)的架构,主要分为三部分。底层Linux内核只提供基本功能;其他的应用软件则由各公司自行开发,部分程序以Java编写。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
- 必须设为 ≥ 65535:
net.core.somaxconn = 65535(写入/etc/sysctl.conf后sysctl -p) - 配套调大 TCP backlog:
net.ipv4.tcp_max_syn_backlog = 262144,防 SYN 泛洪压垮队列 - 加速连接复用:
net.ipv4.tcp_tw_reuse = 1,避免大量TIME_WAIT占满端口 - 放宽本地端口范围:
net.ipv4.ip_local_port_range = 1024 65535,让客户端能建更多 outbound 连接
nf_conntrack 表满会导致连接随机断连
Linux 内核用 nf_conntrack 跟踪每个 TCP 连接状态,默认只存 65536 条。表满后内核日志出现 nf_conntrack: table full, dropping packet,现象是 ping 通但 WebSocket 握手失败、已建连接秒断,且无明确错误码。
- 查当前值:
cat /proc/sys/net/netfilter/nf_conntrack_max - 永久扩容:在
/etc/sysctl.conf加net.netfilter.nf_conntrack_max = 1048576 - 若启用了 conntrack 模块但没显式配置,它可能沿用极低的默认值(如 65536),务必检查
- 注意:调整后无需重启,但已有连接不会自动纳入新表,需等旧连接自然退出
别只盯着 ulimit,内存和 CPU 早就在拖后腿
每 1000 个连接约吃掉 1MB 内存(不含业务数据),8 核 CPU 上跑 50 万连接,光调度开销就能把 sys 时间拉高。系统参数调完,连接数上去了,但响应延迟飙升,大概率是这三件事没做:
- 禁用 Nginx 缓冲:
proxy_buffering off+proxy_cache off,否则消息堆积在 proxy 层 - 服务端改用 epoll/kqueue 轮询(非 “一连接一 goroutine” 或 “一连接一线程”),Go 用
gobwas/ws,PHP Workerman 启用Libevent,Node.js 确保libuv正常加载 - 缓冲区池化:gorilla/websocket 的
WriteBufferPool必须配sync.Pool,否则百万连接光[][]byte就占满 4GB+
系统参数调优不是“设完就完”,nf_conntrack_max 和 ip_local_port_range 这两个值最容易被忽略,尤其在 NAT 网关或容器环境里,它们失效时几乎不报错,只让连接变得“间歇性不可靠”。










