一、概述
在使用JMeter做性能测试时,需要查看压测过程中请求的响应情况,如需要实时显示20w qps的压测数据监控,接下来使用JMeter+Influxdb+Grafana方案打造压测可视化实时监控
- 数据流程
JMeter引入Backend Listener,用于在压测过程中实时发送统计指标数据给时序数据库Influxdb,通过配置Grafana数据源连接到Influxdb,就可以创建炫酷的可视化看板,并实时获取到测试指标数据
- 处理流程图
二、influxdb介绍
2.1 时序数据库
处理带时间标签(按照时间的顺序变化,即时间序列化)的数据,带时间标签的数据也称为时间序列数据
可以理解成它就像一个sql表,其中时间是它的主键
2.2 influxdb
一款用Go语言编写的开源分布式时序、事件和指标数据库,无需外部依赖。该数据库现在主要用于存储涉及大量的时间戳数据,如DevOps监控数据,APP metrics, loT传感器数据和实时分析数据
2.3 数据DEMO
- 通过grafana查询
SELECT * FROM requestsRaw limit 10
数据:
- 通过java查询
SELECT count(responseTime) as Count FROM requestsRaw GROUP BY requestName
数据:
2.4 名词解释
- 与传统数据库中的名词做比较
influxDB中的名词 | 传统数据库中的概念 |
---|---|
database | 数据库 |
measurement | 数据库中的表 |
points | 表里面的一行数据 |
- influxdb中独有概念
point由时间戳(time)、数据(field)、标签(tags)组成
point属性 | 传统数据库中的概念 |
---|---|
time | 每个数据记录时间,是数据库中的主索引(会自动生成) |
fields | 各种记录值(没有索引的属性)也就是记录的值:温度, 湿度 |
tags | 各种有索引的属性:地区,海拔 |
三、JMeter&influxdb集成
3.1 jmeter配置
- 创建一个测试计划,并添加Backend Listener
- 设置Backend Listener中influxdb的url等信息
- 运行测试,等待运行一段时间
- 查看JMeter是否生成错误日志查看JMeter是否生成错误日志
字段信息
- percentiles
默认百分位设置为“90;95;99”,即百分位数为90%,95%和99% - summaryOnly
summaryOnly=true且配置BackendListenerSamplersList时,jmeter还会发送匹配样本名称的指标
3.2 上报确认
查看fagent表中的数据
SELECT * FROM fagent limit 100
确定已经将统计指标数据成功发送到influxdb
四、grafana&influxdb集成
4.1 grafana介绍
Grafana是一个开源软件,拥有丰富的指标仪表盘和图形编辑器,适用Graphite, Elasticsearch, OpenTSDB, Prometheus,InfluxDB
简单点说就是一套开源WEB可视化平台
4.2 grafana数据源配置
- 打开页面选择配置数据源
- 配置influxdb数据源信息
4.3 数据信息
- 线程数/用户相关指标
test.minAT-Min active threads:最小活跃线程数
test.maxAT-Max active threads:最大活跃线程数
test.meanAT-Mean active threads:活跃线程数
test.startedT-Started threads:启动线程数
test.endedT-Finished threads:结束线程数
- 响应时间指标
.ok.count:采样器的成功响应数
.h.count:每秒点击数
.ok.min:采样器成功最短响应时间
.ok.max:采样器成功最长响应时间
.ok.avg:采样器成功平均响应时间
.ok.pct:采样器成功响应百分比
.ko.count:采样器失败响应数
.ko.min:采样器失败的响应最短时间
.ko.max:采样称失败最长响应时间
.ko.avg:采样器失败平均响应时间
.ko.pct:采样器失败响应百分比
.a.count:采样器响应数(ok.count和ko.count的总和)
.a.min:采样器最小响应时间(ok.count和ko.count的最小值)
.a.max:采样器最大响应时间(ok.count和ko.count的最大值)
.a.avg:采样器平均响应时间(ok.count和ko.count的平均值)
.a.pct:采样器响应百分比(根据和失败样本的总数计算)
4.4 导入grafana展示模版
- 导入文件
- 模板json
如果从零开始自己设计一个好看的Dashboard,估计大家难度较大,其实grafana官网提供丰富的模版的库,可以自己上去找然后进行二次扩展官网模版库
在上面找了一个对应的模板,修改后的模板json数据 influxdb_grafana_v1.0
- 导入模板
4.5 数据展示
五、优化看板
需要展示像jmeter一样的聚合结果数据
5.1 数据上报
使用开源项目JMeter-InfluxDB-Writer对上报数据进行了二次开发
5.2 grafana配置
使用对应对的grafana配置信息,具体的json配置json数据
5.3 报告效果
六、踩坑问题
6.1 问题描述
使用开源组件JMeter-InfluxDB-Writer进行数据上报,将jar放入到jmeter的lib/ext目录下
执行后发现报错
2021-03-05 08:24:19,864 INFO o.a.j.v.b.BackendListener: Backend Listener: Starting worker with class: class rocks.nt.apm.jmeter.JMeterInfluxDBBackendListenerClient and queue capacity: 5000
2021-03-05 08:24:19,945 INFO o.a.j.v.b.BackendListener: Backend Listener: Started worker with class: class rocks.nt.apm.jmeter.JMeterInfluxDBBackendListenerClient
2021-03-05 08:24:23,282 ERROR o.a.j.JMeter: Uncaught exception:
java.lang.IllegalStateException: Failed calling setupTest
at org.apache.jmeter.visualizers.backend.BackendListener.testStarted(BackendListener.java:339) ~[ApacheJMeter_components.jar:5.1.1 r1855137]
at org.apache.jmeter.visualizers.backend.BackendListener.testStarted(BackendListener.java:292) ~[ApacheJMeter_components.jar:5.1.1 r1855137]
at org.apache.jmeter.engine.StandardJMeterEngine.notifyTestListenersOfStart(StandardJMeterEngine.java:206) ~[ApacheJMeter_core.jar:5.2-SNAPSHOT.20190806]
at org.apache.jmeter.engine.StandardJMeterEngine.run(StandardJMeterEngine.java:381) ~[ApacheJMeter_core.jar:5.2-SNAPSHOT.20190806]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_211]
Caused by: java.lang.RuntimeException: <html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>nginx</center>
</body>
</html>
根据报错信息The plain HTTP request was sent to HTTPS port
,应该是未支持https请求
6.2 查看源码
查看JMeter-InfluxDB-Writer源码中rc/main/java/rocks/nt/apm/jmeter/config/influxdb/InfluxDBConfig.java
代码文件
在源码中已经增加influxHTTPScheme字段来解决这个问题,增加该字段设置,但是仍失败,为什么最新包请求https请求仍提示报错呢?
6.3 issue
查看issue,发现有issue提出对应的问题
此问题在另外一个issue中已经标为已解决
- 解决代码
6.4 包版本
但是为何最新包打包日期在该代码提交时间之后,代码逻辑没有问题,但是为什么就是不生效呢?
解压最新的jar包
jar -xvf JMeter-InfluxDB-Writer-plugin-1.2.jar
将文件/rocks/nt/apm/jmeter/config/influxdb/InfluxDBConfig.class
拖拽到IntelliJ IDEA,IDEA自动反编译为Java文件
发现其实最新包并未包含最新提交的代码
其实也有人在issue中提到最新包版本的问题
6.5 重新打包
项目使用的是gradle
方式打包,根据build.gradle
文件
- 依赖包
dependencies {
compileOnly group: 'org.apache.jmeter', name: 'ApacheJMeter_core', version: '3.1'
compileOnly group: 'org.apache.jmeter', name: 'ApacheJMeter_components', version: '3.1'
compile group: 'org.influxdb', name: 'influxdb-java', version: '2.4'
}
- 打包操作
- 调用异常
可正常打包,但是打包后调用jar包,抛异常
说明并未将依赖文件完全打包ok
- 问题解决
使用一种比较搓的方式,替换文件:
将解决问题的代码问题通过maven打包然后替换原打包文件的对应InfluxDBConfig.class文件
重新压缩jar包后可正常调用
- 新jar包
其实eostermueller/JMeter-InfluxDB-Writer forked from NovatecConsulting/JMeter-InfluxDB-Writer 项目
针对修复问题的代码进行了打包,但是不晓得为什么可以打包成功
下载后重新替换lib/ext上的jar文件,可正常实现逻辑