使用jmeter压测Netty通讯服务
项目中使用
netty
框架开发底层通讯服务器模块。设备与通讯服务器采用tcp长连接
的通讯方式。建立链接过程使用ssl
对连接通道进行加密。建立连接后定时向服务器发送心跳数据。
测试目标
- 单台
netty server
维持长连接数量。 - 长连接数量增长下
tps
指数。 - 长连接数量增长下
jvm的堆栈
内存变化。
测试工具
- jmeter
- jvisualvm
数据准备
编写脚本准备100W
终端信息。直接上代码。
|
|
- 使用
UUID
生成100W mac
地址 - 再使用生成的
mac
地址分别生成sql
脚本,添加到redis
中 - 将
mac
信息使用redis
的哈希表数据结构进行存储redis.hset("dev_mac",String.valueOf(c), mac);
dev_mac
作为key
循环mac
集合的index
作为hash_key
,mac
作为hash_value
。这样处理方便多机分布式压测。 - 循环mac地址集合生成
sql
脚本,为了进行批处理操作,每5000
条mac
数据作为一个insert into
语句 - 测试脚本运行结束后,将生成的
sql
脚本source
到数据库中。
压力测试脚本
直接上代码
|
|
- 编写自定义压力测试脚本之前需要几部操作。
- 找到
jmeter
安装目录/apache-jmeter-3.2/lib/ext
将ext
目录下的ApacheJMeter_core.jar
和ApacheJMeter_java.jar
引入进测试脚本的工程中。 - 将主类
extends AbstractJavaSamplerClient
覆盖其中的两个方法runTest
和setupTest
。 - 在
setupTest
方法中生成实例SampleResult
对SampleResult
进行设置 然后在runTest
方法中进行添加。
- 找到
- 将编写好的脚本打包成
jar
导入到jmeter
目录/apache-jmeter-3.2/lib/ext
中 , 再将压测脚本所需要的依赖包也导入到/apache-jmeter-3.2/lib/ext
中。 - 打开
jmeter gui
添加测试计划,编写测试计划,具体测试计划的线程组编辑下面再介绍。 - 使用命令进行压力测试
sh ./jmeter.sh -n -t /home/wanglp/communication-pressure-test/device-info/csjh.jmx
-n
表示no gui
-t
表示编写的测试计划。
测试计划的线程组编写
- 添加测试任务,再在测试计划下添加线程组,如图
- 线程数: 表示启动的线程总数。
- Ramp-up period : 表示多少秒后将设置的线程数全部启动。
- 循环次数: 表示该线程组配置循环执行几次。
Jvisualvm 的使用
jvisualvm
用来监控java
程序的堆栈内存
,cpu
,线程
,类加载
数等信息的使用情况。jvisualvm
程序包含在 jdk
家目录下 bin
目录下。为使得 jvisualvm
监控远程的 java
程序 需要为远程的java
程序的启动脚本添加jmx
参数。
|
|
其中 jmx
连接的端口。启动后远程程序后,再回到本机的 jvisualvm
,在远程一栏中添加远程主机,添加之后,再在远程主机下面添加 jmx
连接。
如图:
监控 jvisualvm
参数 如图:
测试报告
线程数 | 栈内存 | 堆内存 | 压测持续时间 | Server 状态 |
---|---|---|---|---|
3000 | 128M | 256M | 1 小时 18 分 34 秒 | down |
测试发现的问题
- 从微服务获取证书时间长,将线程启动频率调整至 1 thread / 3s 以内时,微服务堆内存溢出。
- 随着压测时间的加长,
netty server
的堆内存持续增加,直至堆内存溢出。