JMeter混合REST与WebSocket接口压测时VM资源占用过高咨询
JMeter混合REST与WebSocket压测资源占用过高问题解答
一、这种情况是否正常?
WebSocket属于长连接协议,和REST的短连接模式本质不同:每个压测用户会维持一个持续的WebSocket连接,2000用户就意味着VM要同时维护2000个长连接,还要处理连接的心跳、状态同步等额外逻辑。因此相比纯REST压测,VM的CPU、内存、网络资源利用率升高是正常现象,但如果资源占用高到压测无法稳定运行(比如频繁报错、线程阻塞),就需要排查是否存在操作失误或可优化点。
二、可能存在的操作失误
- WebSocket连接未复用:如果脚本中每个请求都新建WebSocket连接,而不是让每个线程(用户)复用同一个连接,会导致连接数暴增,快速耗尽VM的文件句柄、内存资源
- JSR223采样器使用不当:用了Beanshell等低效脚本语言,或者没勾选
Compile Script选项,导致脚本每次执行都重新编译,额外消耗CPU - 连接泄漏:测试结束或用户流程结束后,未主动关闭WebSocket连接,闲置连接持续占用资源
- 压测配置不合理:2000用户维持长连接的同时,每分钟2000事务的负载叠加,可能超出当前VM的资源承载上限
三、优化脚本资源占用的方法
1. WebSocket连接优化
- 复用连接:确保每个线程仅建立一次WebSocket连接,后续所有WebSocket请求都复用该连接,避免频繁创建、销毁连接的开销
- 主动关闭连接:在用户流程结束或测试收尾阶段,调用WebSocket的关闭方法,及时释放连接资源
- 调整心跳策略:如果服务端要求心跳,设置合理的心跳间隔,避免过于频繁的心跳包消耗网络和CPU资源
2. JSR223采样器优化
- 改用Groovy语言:Groovy的执行效率远高于Beanshell,JMeter对Groovy的原生支持更好,能大幅降低脚本执行的资源消耗
- 开启脚本编译:勾选JSR223采样器的
Compile Script选项,编译后的脚本无需重复编译,减少CPU开销 - 用JMeter内置函数替代脚本:变量创建、重命名这类简单操作,直接用
${__setProperty}、${__renameVar}等内置函数,完全可以替代JSR223脚本,避免脚本执行的额外消耗
3. VM与压测配置调整
- 升级VM资源:如果当前VM内存、CPU不足,适当调高配置(比如内存给到8G以上,CPU核心数4核及以上),满足长连接的资源需求
- 逐步调整压测参数:先降低用户数,逐步增加,观察资源变化,找到VM能稳定承载的最大用户量;也可以调整事务量,避免短时间内负载突增
- 排查GC问题:通过
-Xloggc:gc.log参数开启JMeter的GC日志,分析是否存在内存泄漏或频繁GC的情况,针对性优化内存占用 - 分布式压测:单VM资源瓶颈无法解决时,把用户拆分到多个JMeter节点,分摊资源压力
4. 其他细节优化
- 禁用冗余监听器:只保留聚合报告、后端监听器这类必要的监听器,关闭查看结果树、图形结果等消耗资源的监听器
- 用非GUI模式执行:GUI模式会消耗大量CPU和内存,改用命令行模式(
jmeter -n -t testplan.jmx -l result.jtl)执行压测,性能提升明显 - 调整JMeter配置:修改
jmeter.properties,开启REST连接复用(httpclient.reuseconnections=true),设置合理的WebSocket闲置连接超时时间(ws.max.connection.idle.time),减少不必要的资源占用
内容的提问来源于stack exchange,提问作者Nathan Antony
相关产品推荐
相关产品推荐

