通过jmeter对websocket后台做压测

news2024/12/30 2:35:31

后台使用java程序,通过springboot集成的stomp协议暴露websocket接口,所以下文测试过程会有特定的stomp报文,无需在意,关注流程即可
本次测试使用jmeter模拟大量用户接收群消息的场景,可覆盖连接数以及消息并发的压测

一、jmeter下载安装

下载地址
https://jmeter.apache.org/download_jmeter.cgi
在这里插入图片描述
下载zip安装包到本地解压
在这里插入图片描述
进入/bin目录,执行jmeter.bat启动
在这里插入图片描述
打开一个命令行窗口和一个GUI窗口,启动成功
在这里插入图片描述
在这里插入图片描述
可以通过Options -> Choose Language -> Chinese切换语言为中文
在这里插入图片描述

二、安装JMeter WebSocket Samplers 插件

jmeter默认不支持websocket协议,需要安装插件

下载地址
https://bitbucket.org/pjtr/jmeter-websocket-samplers/downloads/?spm=a2c4g.11186623.0.0.6cfd2486vZsEcu
在这里插入图片描述
下载jar包后,复制到jmeter目录的lib/ext下
在这里插入图片描述
重启jmeter,添加一个线程组
Test Plan右键 -> 添加 -> 线程(用户) -> 线程组
在这里插入图片描述
然后线程组右键 -> 添加 -> 取样器,可以看到websocket的组件,则插件安装成功
在这里插入图片描述

三、通过postman测试websocket连接

在开始jmeter压测前,先通过postman测试两个连接的群发消息功能正常

1、新建id为1002用户的websocket连接

输入后台握手地址,其中1002是sessionId,实际会由客户端随机生成
点击Connect
在这里插入图片描述
可以看到握手成功,后台响应了一个 o,此时已经完成协议升级
在这里插入图片描述
然后输入以下stomp指令,点击send
[“CONNECT\nbusinessId:5\nmemberId:1002\naccept-version:1.1,1.0\nheart-beat:10000,10000\n\n\u0000”,“SUBSCRIBE\nbusinessId:5\nmemberId:1002\nid:sub-1\ndestination:/topic/12344321\n\n\u0000”]

这个指令是stomp协议的内容,可以不用关注,简单理解为向后台发送一条消息,订阅了一个名为12344321的队列
在这里插入图片描述发送成功,服务端针对CONNECT指令响应了a[“CONNECTED\nversion:1.1\nheart-beat:0,0\nuser-name:1002\n\n\u0000”]
在这里插入图片描述

2、新建id为1003用户的websocket连接

重复上述步骤,把地址栏以及stomp指令里的1002改成1003
在这里插入图片描述

3、通过1002用户发送群消息

在1002的连接上输入以下指令,向群组12344321发送一条消息

[“SEND\nbusinessId:5\nmemberId:1002\ndestination:/websocket/sendToGroup\ncontent-length:110\n\n{“senderId”:“1002”,“receiverId”:“12344321”,“messageContent”:“hello everyone”,“messageType”:1,“receiverType”:2}\u0000”]
在这里插入图片描述发送后,由于1002自身也订阅了群组12344321,所以他也收到了服务端的推送
在这里插入图片描述打开1003的窗口,同样收到了群消息
在这里插入图片描述为方便测试,后台提供了接口,查看websocket连接数以及对应的IP和端口
在这里插入图片描述
在这里插入图片描述
通过本地cmd执行netstat命令,可以查看到这两个端口在使用中
在这里插入图片描述
websocket后端工作正常,接下来可以着手开始用jmeter压测

四、jmeter压测

先观察下插件提供的几个Websocket测试组件
在这里插入图片描述
Open Connection用于开启一个websocket连接,会完成协议升级
Single Write 用于向服务端发送数据,看名字,Single,只能发送一次,如果需要发送多次,可以建多个WebSocket Single Write Sampler
Single Read 用于接收服务端的推送,同样只能接收一次,如果要接收多次消息,要建多个
request-response 一个发送以及一个接收,相当于Write + Read

jmeter压测后可以保持连接活跃,但并不能像聊天窗口一样随时发送和接收消息,所以需要针对自己的测试场景组合这几个组件

新建计数器

先创建一个计数器,用以模拟不同用户建立连接
线程组右键 -> 添加 -> 配置元件 -> 计数器
在这里插入图片描述
设置计数器从2000开始,每次递增1,引用名称填sessionId,这个相当于变量名,后续可以用在请求地址或者请求参数里
在这里插入图片描述

新建WebSocket Open Connection

用于握手升级协议

线程组右键 -> 添加 -> 取样器 -> Websocket Open Connection
在这里插入图片描述
在新建的Websocket Open Connection中填入后台协议升级的接口IP、端口以及路径地址
在这里插入图片描述其中路径里使用了变量${sessionId}

新建Websocket Single Write

在这里插入图片描述
在Connection里选中use existing connection,也就是会使用上面WebSocket Open Connection组件建立的连接

然后在Request data里填入stomp指令,完成用户身份绑定,以及订阅群组12344321

[“CONNECT\nbusinessId:5\nmemberId:KaTeX parse error: Undefined control sequence: \naccept at position 12: {sessionId}\̲n̲a̲c̲c̲e̲p̲t̲-version:1.1,1.…{sessionId}\nid:sub-1\ndestination:/topic/12344321\n\n\u0000”]
在这里插入图片描述

新建WebSocket Single Read

在这里插入图片描述
通过之前的postman测试可以发现,在握手成功以及CONNECT指令发送成功后,服务端都会有一个响应

(实际上spring内置的stomp集成,服务端会针对每一个客户端连接启动一个类似心跳的任务,每隔25秒推送一个报文h,这里为了方便测试,修改源码把这个任务停掉了,如果你的websocket服务端也有类似的定时推送,测试过程中需要留意,因为每个Read Sampler只能接收一次消息)
在这里插入图片描述
所以我们这里要建立3个Read Sampler组件,前2个用于接收服务端的响应,第3个用于等待接收群消息
Read Sampler的Connection同样要选择 use existing connection
在这里插入图片描述
为了方便测试,把这个3个Read Sampler名字后面分别加上 s e s s i o n I d − 握手、 {sessionId}-握手、 sessionId握手、{sessionId}-订阅群组、${sessionId}-群消息

其中第3个Read Sampler由于要接收消息,将它的Response Timeout调大点
在这里插入图片描述

添加结果监听器

线程组右键 -> 添加 -> 监听器 -> 查看结果树
在这里插入图片描述

调整线程数

线程数调整为12000
在这里插入图片描述

执行测试

在这里插入图片描述
执行完后,结果里目前只有握手和订阅群组的响应,群消息还没发,所以第3个Read Sampler在等待中
在这里插入图片描述
通过后台接口查看连接数,包括了jmeter的12000个连接以及postman的2个连接
在这里插入图片描述
端口号
在这里插入图片描述
然后通过postman的用户1002再次发布群消息
在这里插入图片描述

jmeter里第3个Reader收到了消息
在这里插入图片描述单机能建立的连接数受端口号限制,jmeter建立连接使用的端口号大多数从49000开始,到最大端口号65535,再加上其他进程占用的端口,瓶颈大概在16000

比如把线程数调整到20000,执行到16000就开始增长缓慢甚至卡住了,jmeter也有报错无连接可以复用
所以如果需要对服务器做连接数上限等的压测,比如数十万连接,就需要多台服务器配合了
在这里插入图片描述

踩坑记录

通过上面最后一张图,可以看到jmeter其实会复用一些连接,如果只通过WebSocket Open Connection来试图测试连接上限,会发现后台连接会短暂达到线程组的指定数字,但很快会降低到一个随机值,期间没有日志,但多测几次后,又有可能所有连接都保持活跃,线程组的线程数越多,这个现象越容易出现

通过对stomp的代码排查,发现部分连接被close掉的过程中,有一个异常被catch掉了,修改源码后抛出,可以在控制台看到一个EOF Exception
在这里插入图片描述
这个异常通常出现在读取的过程中意外遇到输入流末尾导致,放在这个场景里,就是jmeter在某个端口建立了连接A,后来又关闭A,在同一个端口上建立了连接B,在压测的过程中,这个变化非常快,服务端还没来得及做清理,于是在服务端看来,A和B都是某个IP的特定端口,是同一个socket连接,所以读取数据的时候就发生了混乱

至于为什么jmeter会复用这个端口,我的理解是jmeter的几个websocket组件,不管是Single Read Sampler还是Open Connection,其实都是一次性的,并不能持续的接收或者发送消息,那么当其执行完毕,jmeter认为其使命已经结束,在资源紧张的情况下,可以收回该端口了

通过单纯的OpenConnection测试,发现jmeter日志里确实有标明某线程已经Done并且Finished了
在这里插入图片描述
而通过本文测试接收群消息的方式,第3个Read Sampler的timeout时间很长,在群消息到来前,这个线程的任务并没有结束,所以也就不能清理并复用其端口了,于是所有的连接都通过不同的端口建立

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2033363.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CentOS7.6 RabbitMQ消息队列集群部署——实施方案

1、前期环境准备(每个主机都配置) 1.准备三台主机 IP地址主机名内存大小192.168.200.10 rabbitmq1 2G192.168.200.11rabbitmq22G192.168.200.55rabbitmq32G 2. 设置主机名 hostnamectl set-hostname 主机名suexit Ctrlr 3. 设置IP地址然后重启网卡 …

深度学习与图像修复:ADetailer插件在Stable Diffusion中的应用

文章目录 引言ADetailer插件介绍插件安装常用模型控制提示词参数配置参数详解 实践建议 示例插件的对比:1. ADetailer插件2. Photoshop插件(如Nik Collection)3. GIMP插件(如GMIC)4. Affinity Photo插件 结语 引言 无…

【物联网】(蓝牙篇)微信小程序ios如何自动打开蓝牙

微信小程序打开蓝牙的便捷之道——微信小程序ios如何自动打开蓝牙 随着智能手机蓝牙技术和物联网产品的普及,很多人在使用微信小程序时,都希望能够更便捷地打开蓝牙功能。 在iOS系统上,由于其封闭性和权限控制严格,使得自动打开蓝…

OpenGL ES->GLSurfaceView进行点、线段、三角形等基本图元的绘制

GLSurfaceView代码见OpenGL ES->顶点着色器和片段着色器代码,只修改顶点数组,片段着色器的颜色,和绘制方式进行不同图元绘制 绘制点 GL_POINTS方式 // 顶点数据 val vertices floatArrayOf(0.8f, -0.8f, 0.0f,-0.8f, -0.8f, 0…

Python大数据分析——SVM模型(支持向量机)

Python大数据分析——SVM模型(支持向量机) 认知模型介绍距离计算模型思想目标函数函数与几何间隔 线性可分SVM模型目标函数函数代码 非线性可分SVM模型目标函数函数代码 示例手写体字母识别森林火灾面积预测 认知模型 介绍 超平面的理解:在…

Stable Diffusion绘画 | 进阶语法

控制提示词生效时间 使用格式1:[提示词:0-1数值] 举例:forest,lots of trees and stones,[flowers:0.7] 其中 [flowers:0.7] 表示整体画面采样值达到70%的进程以后,才开始计算花的采样。 因此,花的数量仅仅只跑了末段的30%&am…

LeetCode之回溯

1.全排列 1.1 题目 1.2 题解 LeetCode 力扣官方题解 1.3 代码 class Solution {public List<List<Integer>> permute(int[] nums) {// 创建一个空的列表 res&#xff0c;用于存储所有的排列结果List<List<Integer>> res new ArrayList<>();/…

C++入门基础:数据类型与条件判断语句

数据类型 基础数据类型 整型&#xff08;Integral Types&#xff09; int&#xff1a;基本的整型&#xff0c;大小依赖于编译器和平台&#xff0c;通常是32位或64位。 short&#xff1a;短整型&#xff0c;通常是16位。 long&#xff1a;长整型&#xff0c;大小依赖于编译…

本地部署Code Llama大模型结合Text generation Web UI远程运行LLM

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

pdf拆分成一页一页,怎么操作?pdf拆分的好用方法

pdf拆分成一页一页&#xff0c;怎么操作&#xff1f;PDF文件的拆分通常涉及到以下几个常见场景和需求&#xff1a;首先&#xff0c;PDF文件可能包含大量的页面&#xff0c;例如数百页的电子书或详尽的技术手册。在某些情况下&#xff0c;用户可能只需要处理其中的几页或者想要单…

揭秘!亚马逊与速卖通自养号测评:必备资源与技术要点

面对测评服务商的种种承诺&#xff0c;其真实性往往难以验证&#xff0c;而在像Facebook这样的社交平台上自行寻找测评资源&#xff0c;也显得相当困难和不切实际。随着产品即将上架&#xff0c;寻找一个可靠的测评服务似乎并不那么容易。因此&#xff0c;对于亚马逊等跨境平台…

运动耳机哪个品牌好用?五款质量一流品牌推荐!

运动耳机无疑是运动爱好者的绝佳伴侣&#xff0c;让每一次挥汗如雨的瞬间都伴随着无与伦比的音乐盛宴与舒适的佩戴感受。特别是对于跑步爱好者而言&#xff0c;一款优秀的运动耳机更是不可或缺的装备。然而&#xff0c;市场上的运动耳机种类繁多&#xff0c;质量也千差万别&…

Mirror学习笔记(五)概念指南

文章目录 一、Authority(权限)二、IDs(身份编号)三、Attributes(属性)四、Time Synchronization(同步时间)五、Data types(数据类型)六、Serialization(序列化)七、Synchronization(同步)八、Communications(通讯)九、GameObject(游戏对象) 顶层脚本API: Mirror是一个高级网络库…

Qt信号与槽-思维导图-学习笔记

Qt 信号与槽 Qt 信号与槽机制 基本概念 信号与槽机制&#xff1a;Qt 编程的基础与创新&#xff0c;使得处理界面组件交互操作更加直观和简单 信号&#xff08;Signal&#xff09;&#xff1a;在特定情况下被发射的事件&#xff0c;如按钮点击的 clicked() 信号、组合框项变化…

服务器数据恢复—服务器raid常见故障产生原因数据恢复方案

磁盘阵列&#xff08;raid&#xff09;是一种将多块物理硬盘整合成一个虚拟存储的技术。raid模块相当于一个存储管理中间层&#xff0c;上层接收并执行操作系统及文件系统的数据读写指令&#xff0c;下层管理数据在各个物理硬盘上的存储及读写。相对于单独的物理硬盘&#xff0…

超算互联网-Stable Diffusion 2.1文生图教程

一、名词简介 1. 超算互联网 超算互联网是一种基于云计算的高性能计算平台&#xff0c;用户可以通过互联网接入超级计算资源。它集成了大量的计算节点&#xff0c;提供强大的计算能力&#xff0c;适用于科学计算、深度学习、人工智能等领域。用户可以利用超算互联网平台运行复…

Neural Architecture Search:使用Ultralytics框架进行YOLO-NAS目标检测

Neural Architecture Search&#xff1a;使用Ultralytics框架进行YOLO-NAS目标检测 前言相关介绍前提条件实验环境安装环境项目地址LinuxWindows 使用Ultralytics框架进行YOLO-NAS目标检测进行预测进行验证 参考文献 前言 由于本人水平有限&#xff0c;难免出现错漏&#xff0c…

旧照片如何修复翻新?这3个方法值得收藏

旧照片如何修复翻新&#xff1f;旧照片的修复翻新是一项既具有挑战性又充满意义的工作。它不仅仅是一个简单的图像处理过程&#xff0c;更是一次穿越时空的旅行&#xff0c;让那些被岁月遗忘的珍贵回忆重新焕发光彩。每一张旧照片都承载着独特的历史和情感价值&#xff0c;通过…

CTF-PWN-web pwn初探

文章目录 参考简介生命周期php扩展模块搭建php扩展模块初始化编写扩展模块编译扩展模块测试 检查调试相关技巧/proc/self/maps泄露php堆PHP 内存管理机制空闲堆块管理示例解释1. 内存分配示例2. 内存释放示例3. tcache poison 攻击 溢出mprotect改栈权限反弹shell 常用phpexp 参…

[Pytorch案例实践008]基于卷积神经网络和通道注意力机制的图像分类实战

一、项目介绍 这是一个蜜蜂、蚂蚁图像分类项目&#xff0c;旨在使用卷积神经网络&#xff08;CNN&#xff09;结合SE&#xff08;Squeeze-and-Excitation&#xff09;模块进行二分类任务。以下是项目的详细介绍&#xff1a; 项目背景 图像分类是计算机视觉中的一个基本任务&a…