面对实时通讯(如在线聊天、游戏指令、行情推送)的压力测试,JMeter配合WebSocke 插件是性价比很高的选择。
一、环境准备
1. JMeter本体
下载5.5+ 版本(官网),解压即可。
2. WebSocket 插件
最主流、功能最完整的插件是 WebSocket Samplers by Maciej Zaleski。
安装方式:打开 JMeter - Options - Plugins Manager,在 Available Plugins中搜索WebSocket Samplers并安装。
如果找不到Plugins Manager,先安装JMeter Plugins Manager。
安装后,在取样器列表中可看到:
WebSocket Open Connection:建立连接
WebSocket request-response Sampler:发送请求并同步等待响应
WebSocket Single Write Sampler:仅发送,不等待响应
WebSocket Single Read Sampler:仅等待接收一条(或一段)消息
WebSocket Close:关闭连接
这些组件可组合使用,完美模拟长连接下的各种通信方式。
二、从一个Echo测试开始配置
我们模拟一个完整生命周期:建立连接 - 发送消息 - 接收回显 - 关闭连接。
假设测试地址为 ws://echo.websocket.org(已停止,可用 ws://ws.ifelse.io 或自己搭建的 Echo 服务)。
1. 测试计划结构
Thread Group(线程组:模拟并发用户)
WebSocket Open Connection
WebSocket request-response Sampler
WebSocket Close
View Results Tree(调试监听器)
2. 配置WebSocket Open Connection
Server name or IP:echo.websocket.org(或 ws.ifelse.io)
Port:80(ws 默认 80,wss 默认 443)
Protocol:留空表示 ws,如果为 wss 则填 https
Path:/
Connection id:myWsConn ⭐
这个变量名非常重要,后续所有操作都要通过它引用同一个连接,避免每个取样器重复建立连接。
其他超时时间可暂用默认。
3. 配置WebSocket request-response Sampler
Connection:选择 use existing connection
Connection id:myWsConn(和上面一致)
Data type:Text,也可选 Binary
Request data:{"type":"echo","msg":"hello"} 或纯文本 Hello WebSocket!
Response timeout (ms):2000(等待服务器回包的超时)
4. 配置WebSocket Close
Connection id:myWsConn
Close status:1000(正常关闭)
运行线程组(1 个线程,循环 1 次),在View Results Tree中应能看到绿色成功的取样结果,响应数据为服务器回包内容。
三、实时推送场景模拟
实际业务中客户端常常:
建立连接后保持在线
间歇性发送心跳/订阅指令
不断接收服务端推送,而不是一问一答
这就需要更灵活的取样器组合。
场景:模拟聊天室客户端
建立连接后发送登录 Token
循环接收推送消息,并每隔 10 秒发送一次心跳 Ping
最后正常断开
脚本结构:
Thread Group
WebSocket Open Connection (connId: chatConn)
WebSocket request-response Sampler (登录)
Request Data: {"action":"login","token":"${userToken}"}
Response timeout: 3000
Loop Controller (无限循环,或通过计数器控制时长)
WebSocket Single Write Sampler (心跳)
Connection: use existing (chatConn)
Request Data: PING
(不等待响应)
Constant Timer (10秒间隔)
WebSocket Single Read Sampler (接收推送)
Connection: use existing (chatConn)
Timeout (milliseconds): 5000
(读取一条消息,如果无新消息会在超时后退出)
WebSocket Close (connId: chatConn)
说明:
Single Read Sampler 默认从连接缓冲区读取一条完整的 WebSocket 消息。如果服务器一直在推送,它将不断被循环中的下一次读取继续消费。
超时设置:如果设置 5000ms,当 5 秒内无消息到达,该取样器会标记为失败(或警告),并跳出,循环继续执行下一次心跳和读操作。
为了不让超时导致测试报告充满错误,可以在 Single Read Sampler 后添加 Response Assertion 勾选 Ignore Status,或使用 If Controller 判断响应代码。
如果希望不断阻塞等待消息直到测试结束,可在 While Controller 中用条件永远真,但注意合理设置 timeout 避免线程僵死。
四、多用户高并发压力测试实现
将脚本放入并发用户模型中:
线程组设置
线程数:500(模拟 500 个同时在线用户)
Ramp-up 时间:60 秒(每秒启动约 8 个连接,避免冲击)
循环次数:勾选 Forever,并设置调度器 Duration 为 600 秒(不断压测 10 分钟)
参数化
使用 CSV Data Set Config 从文件读取不同的登录 Token、用户名、消息内容等,绑定到变量 ${userToken}。
连接复用和独立性
JMeter 的每个线程是独立运行的,不同线程之间的 WebSocket 连接互不干扰。我们的 Connection id 只在同一线程内有效,所以 500 个线程会建立 500 个独立的 WebSocket 连接,完全模拟真实客户端。
SSL / WSS 配置
如果服务器为 wss://,除了在 Open Connection 中设置 Protocol 为 https 并填写 443 端口外,还要将证书导入 JMeter 的 Truststore 或修改 jmeter.properties 绕过证书证实(仅测试环境):
properties
# 在 bin/jmeter.properties 中
javax.net.ssl.trustStore=
# 同时注释掉全部SSL相关,并在HTTP Request默认值(如果有)忽略
更安全的做法是使用JMeter的SSL Manager加载证书。
五、结果分析监控
监听器:
View Results Tree:调试时使用,压测时禁用或仅记录错误。
Aggregate Report:观察平均响应时间、吞吐量、错误率。
Backend Listener:对接 InfluxDB + Grafana,实现实时趋势监控。
观察:
WebSocket 建立连接耗时:Open Connection 取样器的响应时间,如果过高检查网络或握手过程。
读写响应时间:Single Read 的延迟可能显示推送时延,但注意其受到 timeout 设置影响,应结合业务分析。
错误率:连接超时、读取超时、HTTP 500 状态码(如果握手返回 HTTP 错误),需检查服务器端并发连接数和消息处理能力。
系统资源:压测时必须监控服务器 CPU、内存、网络 TCP 连接数(netstat -ant | grep ESTABLISHED | wc -l),以及端口范围是不是耗尽。
六、避坑技巧
连接数限制
单台 JMeter 压测机受限于操作系统端口数,一般建议 ulimit -n 65535 并调整 tcp_tw_reuse。5000 个以上并发连接建议使用分布式压测。
读超时和循环
如果使用 While Controller 无限循环 Single Read,且服务器静默时间超过 timeout,线程将不断产生 timeout 失败并重试,可能导致大量错误日志。解决方案是:
将 timeout 设为一个相对较大的值(如 30 秒),并接受偶尔的超时。
在 Single Read 后添加 JSR223 PostProcessor 检测响应码,如果是超时则忽略或 continue。
流式二进制处理
WebSocket request-response Sampler 支持 Binary 数据类型,可直接发送和接收二进制帧。如果需分析二进制内容(如 Protobuf),可使用 JSR223 取样器编写 Groovy 脚本处理原始字节。
测试脚本录制
JMeter 无法直接录制 WebSocket 流量,推荐使用浏览器 DevTools 的 Network → WS 标签,查看实际交互的数据帧,手工编写成上述取样器请求。这也是最准确的方式。
模拟断线重连
可在循环中捕捉到连接断开错误后,利用 If Controller 判断 ${JMeterThread.last_sample_ok} 是不是为 false,然后跳转到 Open Connection 重新连接,保证长连接测试的健壮性。
七、脚本示例
目的: 100 用户并发,向 Echo 服务每秒发送一条消息并接收回显,不断 5 分钟。
Test Plan结构:
User Defined Variables:server=ws.ifelse.io , port=80
Thread Group:100 线程,Ramp-up 30s,Duration 300s
CSV Data Set Config(可选,如消息内容文件)
WebSocket Open Connection:Server: ${server}, Port: ${port}, Connection id: echo
Loop Controller:勾选 Forever
WebSocket request-response Sampler
Connection: use existing, echo
Request data: Hello ${__counter(TRUE,)} (内含自增计数器)
Timeout: 2000
Constant Timer:1000 ms(控制每秒发送一条)
WebSocket Close:connId: echo
Listeners: Aggregate Report, View Results Tree (仅记录错误)
保存并运行,即可得到 100 路并发的 WebSocket 消息吞吐量和响应延迟。
JMeter WebSocket 取样器的组合能力非常强,几乎可以包括所有实时通讯的压力场景。只需清楚业务交互流程,就能像搭积木一样组装出复杂的长连接测试脚本。