验证nginx代理websocket千级并发需分层观测:先用curl验证握手成功(http/1.1 101)、ss确认established连接增长、后端日志查转发;再用wrk模拟1000长连接,每30秒监控worker res内存、fd数、tcp连接总数;结合日志分析分发均衡与升级成功率;最后检查ulimit、worker_rlimit_nofile及fs.file-max三处系统限制。

要验证 Nginx 代理 WebSocket 在千级并发下的内存与连接占用,关键不是“测出最大值”,而是复现真实长连接行为 + 分层观测资源变化。千级(1000+)已超出浏览器限制,必须用服务端工具模拟,同时关注 Nginx worker 进程的 RES 内存、文件描述符消耗和连接状态分布。
真实并发压测前先确认握手链路通
Nginx 配置没生效时,压测只会放大失败率,不反映真实资源占用。务必在开压前完成三项验证:
- 用 curl 模拟一次标准 WebSocket 握手,检查是否返回
HTTP/1.1 101 Switching Protocolscurl -i -N \ -H "Connection: Upgrade" \ -H "Upgrade: websocket" \ -H "Sec-WebSocket-Key: $(openssl rand -base64 16)" \ http://your-nginx-ip/ws/
- 用
ss -tn | grep :80或netstat -an | grep :443查看 ESTABLISHED 连接数是否随请求增长 - 在后端日志中确认有新连接建立记录,并带唯一标识(如
X-Backend: node-1),证明 Nginx 确实转发且未缓存或拦截
用 wrk 或 JMeter 模拟千级长连接并观测内存趋势
wrk 更轻量、更贴近系统层,适合测 Nginx worker 的内存与 fd 消耗;JMeter 更适合带业务逻辑(如登录、心跳)的场景。
-
wrk 压测命令示例(HTTP 协议层,适用于 ws/wss 后端直连或 Nginx 已配好):
wrk -c 1000 -d 300s --timeout 30s http://your-nginx-ip/ws/
注意:wrk 本身不理解 WebSocket 帧,但它能维持千条 TCP 长连接,足够触发 Nginx 的连接内存分配与 fd 占用。
-
观测要点(每 30 秒执行一次):
-
ps -o pid,vsz,rss,comm -C nginx查看 worker 进程 RES(rss)内存 -
cat /proc/$(pgrep -f "worker process")/limits | grep "Max open files"确认 ulimit 生效 -
ss -s | grep "TCP:"看当前 TCP 连接总数 -
lsof -p $(pgrep -f "worker process") | wc -l统计该 worker 打开的文件描述符数
-
-
典型现象(来自实测数据):
- 初始 RES 约 180–200 MB
- 1000 连接稳定后,RES 上涨约 40–60 MB(每个连接平均新增 40–60 KB 内存)
- 压测结束后 RES 不回落或仅小幅下降(因内存池未释放,属正常行为)
- 若
lsof数远超worker_connections设置值,说明存在 TIME_WAIT 泛滥或连接未正确关闭
通过 Nginx 日志分析连接质量与分发均衡性
光看内存不够,还要确认连接是否被合理分发、有没有异常中断:
- 在
log_format中加入关键变量:log_format websocket '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '$upstream_addr $upstream_response_time $request_time ' '$http_upgrade $http_connection'; - 压测中实时统计:
-
awk '$12 ~ /websocket/ {print $9}' access.log | sort | uniq -c | sort -nr→ 查看各 upstream 实例接收连接数 awk '$10 → 统计超快响应(可能为拒绝或 400)-
awk '$8 == 101 {count++} END {print count}' access.log→ 确认成功升级连接数占比
-
系统级瓶颈排查:别让 ulimit 成为千连天花板
Nginx worker 能否撑住千连,最终卡在操作系统层面:
-
检查并调大三处限制:
- 用户级:
ulimit -n 65535(写入/etc/security/limits.conf) - Nginx 主配置:
worker_rlimit_nofile 65535; - 系统级:
sysctl -w fs.file-max=2097152,并写入/etc/sysctl.conf
- 用户级:
若压测中出现
accept() failed (24: Too many open files)错误,说明已触顶,需回查上述任一环节未生效。
不复杂但容易忽略











