Nginx代理WebSocket压测需四配对配置:强制HTTP/1.1、透传Upgrade/Connection头、设长超时(86400s)、禁用缓冲;压测前须curl验证101响应、抓包确认TCP连接、后端日志验证分发;JMeter压测需正确安装插件、区分ws/wss SSL配置、分布式扩展及完整依赖上传;Nginx日志通过$upstream_addr、$upstream_response_time等字段分析连接质量与瓶颈。

直接用 Nginx 代理 WebSocket 做压力测试,核心不是测 Nginx 本身,而是让它成为可追踪、可分发、可验证的流量枢纽——把真实长连接压力打到后端,同时能看清每条连接去哪了、耗时多少、是否稳定。
WebSocket 代理必须配对的关键项
Nginx 要正确转发 WebSocket 流量,仅 proxy_pass 不够,以下四点缺一不可:
- HTTP/1.1 协议强制启用:proxy_http_version 1.1 是握手成功的前提,HTTP/1.0 会直接失败
- Upgrade 和 Connection 头必须透传:proxy_set_header Upgrade $http_upgrade 和 proxy_set_header Connection "upgrade" 决定服务端是否执行协议切换
- 超时时间要足够长:proxy_read_timeout 和 proxy_send_timeout 建议设为 86400(24 小时),避免空闲连接被误断
- 禁用缓冲提升实时性:proxy_buffering off 可防止消息堆积延迟;若需大消息支持,再单独配 proxy_buffer_size 和 proxy_busy_buffers_size
压测前必须验证的三项连通性
配置完别急着开压,先确认链路真正打通:
- 用 curl 模拟握手请求,检查返回状态码是否为 101 Switching Protocols:
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Sec-WebSocket-Key: $(openssl rand -base64 16)" http://your-nginx-ip/ws/ - 抓包验证 TCP 层连接是否建立成功(Wireshark 过滤 tcp.port == 80 or tcp.port == 443),确认三次握手完成且无 RST
- 在后端服务日志中确认收到连接,并返回唯一标识(如 X-Backend: node-a),证明 Nginx 确实将连接分发到了目标实例
用 JMeter 实现可扩展的 WebSocket 压测
JMeter 是目前最可控的 WebSocket 压测工具,但必须避开常见陷阱:
- 插件安装必须分两步:先装 Plugins Manager,再通过它安装 WebSocket Samplers by Peter Doornbosch;手动丢 JAR 包进 lib/ext 无效
- ws/wss 配置不能只改 URL:wss 必须配 SSL 上下文,否则握手阶段就失败;需在 Test Plan 级添加 HTTP(S) Test Script Recorder 或 JVM 参数指定 trustStore
- 单机压测上限约 2 万连接,突破需分布式:每台压测机 JVM 堆内存建议设为 -Xms4g -Xmx4g,过高反而触发 GC 频繁导致 OOM
- 脚本上传到云平台(如 PTS)时,必须同步上传 .jmx + WebSocket 插件 JAR + 所有自定义依赖(如 proto 类),缺一不可
从 Nginx 日志反推连接质量与瓶颈
开启详细日志后,/var/log/nginx/access.log 里每行都含关键线索:
- $upstream_addr 显示实际连接的后端地址,可用于统计各节点连接数是否均衡
- $upstream_response_time 是 WebSocket 握手完成耗时(单位秒),若持续 >1s,说明后端或网络存在阻塞
- $request_time 是整个请求生命周期(含后续 ping/pong),突增说明连接维持异常或心跳失效
- 配合 log_format 加入 $status 和 $bytes_sent,可识别大量 101 成功但后续无数据的“假连接”



















