背景
日常工作中,經常會用到Jmeter去壓測,畢竟LR還要錢(@¥&*...),而最常用的接口壓力測試,我們都是通過聚合報告去查看壓測結果的,然鵝聚合報告的真的是丑到家了,作為程序猿這當然不能忍!那我們要怎么給它變得好看點捏?
如何華麗變身?
| 方式 |
優點 |
缺點 |
場景 |
| Jmeter+ant+Jenkins |
快捷,上手簡單 |
報告還是不夠美觀、直觀,如果測試接口一多,報告就會顯示臃腫不夠直觀 |
看最終報告 |
| Grafana+Jmeter+Influxdb(推薦) |
數據可視化,數據直觀,篩選功能強大,拓展能力強 |
當然就是要自己部署環境咯,還得了解Influxdb的語法和常用查詢語句,系統方法等..... |
看壓測過程中參數的變化 |
工具介紹
| 工具 |
介紹 |
| Jmeter |
Java語言開發的壓力測試工具(不多介紹) |
| InfluxDB |
Go 語言開發的一個開源分布式時序數據庫,非常適合存儲指標、事件、分析等數據 |
| Grafana |
純 Javascript 開發的前端工具,用於訪問 InfluxDB,自定義報表、顯示圖表等 |

Centos7安裝InfluxDB
備注:博主是自己買的阿里雲服務器哈,就不介紹虛擬機下如何安裝了(畢竟虛擬機很多坑...)
InfluxDB 官網下載路徑:https://portal.influxdata.com/downloads/
1、直接執行以下命令進行安裝:
wget https://dl.influxdata.com/influxdb/releases/influxdb-1.6.3.x86_64.rpm sudo yum localinstall influxdb-1.6.3.x86_64.rpm
2、安裝完成后,修改InfluxDB的配置,主要配置jmeter存儲的數據庫與端口號
vim /etc/influxdb/influxdb.conf
3、找到graphite並且修改它的庫與端口
enabled = true
database = "jmeter" retention-policy = "" bind-address = ":2003" protocol = "tcp" consistency-level = "one"

4、找到http,將前面的#號去掉

5、現在新版本的InfluxDB已取消自帶的數據可視化界面了,舊版的還是有,可通過找到admin,將前面的#號去掉,開放它的UI端口;(該步驟非必須!)
可通過InfluxDB可視化工具來查看我們的數據庫和數據哦,具體安裝和簡單使用參照此篇博文:https://www.cnblogs.com/poloyy/p/12213495.html
[admin] # Determines whether the admin service is enabled. enabled = true # The default bind address used by the admin service. bind-address = ":8083"
6、配置成功后,啟動InfluxDB
啟動命令: systemctl start influxdb.service
查看狀態命令: systemctl status influxdb.service

到此,InfluxDB已安裝並配置完成了!!*:ஐ٩(๑´ᵕ`)۶ஐ:*
特別說明:
- 8083端口:InfluxDB的UI界面展示的端口
- 8086端口:Grafana用來從數據庫取數據的端口
- 2003端口:剛剛設置的,Jmeter往數據庫發數據的端口
Centos7安裝Grafana
Grafana官網下載路徑:https://grafana.com/grafana/download
1、直接執行以下命令進行安裝:
wget https://dl.grafana.com/oss/release/grafana-6.5.2-1.x86_64.rpm sudo yum localinstall grafana-6.5.2-1.x86_64.rpm
2、然后啟動即可
啟動命令: systemctl start grafana-server.service
查看狀態命令: systemctl status grafana-server.service

3、訪問IP加端口 http://xxx.xx.xx.xx:3000 ,輸入用戶名,密碼登錄系統。用戶名與密碼都是"admin",如果能打開頁面則已經成功了!但是...裝環境這東西怎么可能這么簡單??
4、當你查看狀態是active但是訪問3000時是失敗的話,辣么有可能就是你的3000端口還未開放!
跟着這篇文章來操作就可以開放3000端口啦:https://www.cnblogs.com/poloyy/p/12213297.html
5.訪問IP加端口 http://xxx.xx.xx.xx:3000 ,若能訪問到grafana就是成功啦!
配置Jmeter
這里就不教如何安裝Jmeter了哈,主要講Jmeter作為采集端是通過什么采集數據的
步驟一:在線程組中,添加監聽器(Listener)- Backend Listener

步驟二:配置Backend Listener

可以看到,Jmeter默認選中的Implementatin是 GraphiteBackendListenerClient ,它是Jmeter 2.13就開始提供了;在Jmeter 3.2時又加多了一個 InfluxDBBackendListenerClient ,哎~這兩者有什么區別呢?后面會講到!
這里先講選中 GraphiteBackendListenerClient 時,每個配置項的含義
- graphiteHost:InfluxDB安裝的服務器的ip
- graphitePort:端口;默認就是2003,除非你自己安裝InfluxDB時設置了其他端口是哦(可見上面安裝InfluxDB后關於graphite的配置)
- rootMetricsPrefix:指標的根前綴;將測試結果存入數據庫時,不同指標會生成不同表,但這些表都最好要有一個共同的前綴,這個就是了;后面會講到不同的指標的含義(重點哦)
- summaryOnly:當你線程組有多個請求又想知道每個請求的結果數據時,最好填false,因為true只會返回所有請求的集合數據報告,不會輸出每條請求的數據報告
- samplersList:取樣器列表;想收集哪些請求就填哪些,最好用正則去匹配,減輕工作量
- useRegexpForSamplersList:是否使用正則;如果true則使用,samplersList里可以匹配正則表達式
- percentiles:百分比;即類似聚合報告里90% Line,95% Line,99% Line的數據;倘若想要99.9時,需要寫成【99_9】,用下划線代替點
建議:如果想看每個請求的結果數據的話,根據我的截圖進行配置即可;只需改動samplerList來匹配你需要監控的請求,其他不用動!
步驟三:運行Jmeter腳本,查看數據庫
一開始,我的數據庫是只有兩張表的,這里方便演示,就只跑get、post請求了

如果成功了代表結果數據也存進InfluxDB里面了,接下來我們來看看使用 GraphiteBackendListenerClient 時會生成哪些表呢?

可以看到生成了三種前綴的表,分別是: jmeter.all 、 jmeter.get 、 jmeter.post ;最后其實還有 jmeter.test 開頭的表,這個后面會單獨拿出來說
============================================
=== 倘若不想了解每個指標的具體含義,可以跳過下面內容
=== 直接點擊右側目錄,跳轉至配置Grafana,查看下一步
============================================
步驟四:細品指標含義
為什么每個表都有jmeter前綴呢?
因為在Jmeter的Backend Listener配置了rootMetricsPrefix 值為 jmeter. ,你不喜歡前綴或者想起其他名,在Backend Listener里直接改 rootMetricsPrefix 的值就可以了
可以參考下官方文檔的寫法: <rootMetricsPrefix><samplerName>.ok.count ,rootMetricsPrefix和samplerName都是變量,可配置的
接下來,我們來說明下每個前綴的含義
jmeter.all :代表了所有請求;當summaryOnly=true時,就只有samplerName=all的表了
jmeter.get :代表了HTTP請求的名字是get,即samplerName=get
jmeter.post :代表了HTTP請求的名字是post,即samplerName=post
備注:假設你的某個HTTP請求叫【GET請求啊】,辣么你的數據庫就會生成以jmeter.GET請求啊 為前綴的各種表
然后再針對不同指標說下它們的含義
划重點:這里的指標含義都是直接翻譯Jmeter官方文檔的
喜歡英文的小伙伴可以自行查看:http://jmeter.apache.org/usermanual/realtime-results.html
Thread/Virtual Users metrics - 線程/虛擬用戶指標
跟線程組設置相關的
| 指標 | 全稱 | 含義 |
| <rootMetricsPrefix>test.minAT | Min active threads | 最小活躍線程數 |
| <rootMetricsPrefix>test.maxAT | Max active threads | 最大活躍線程數 |
| <rootMetricsPrefix>test.meanAT | Mean active threads | 平均活躍線程數 |
| <rootMetricsPrefix>test.startedT | Started threads | 啟動線程數 |
| <rootMetricsPrefix>test.endedT | Finished threads | 結束線程數 |
Response times metrics - 響應時間指標
划重點:每個sampler都包含了所有響應時間指標,每個sampler的每個指標都會有單獨的一個表存儲結果數據
| 指標 | 含義 |
| <rootMetricsPrefix><samplerName>.ok.count | sampler的成功響應數 |
| <rootMetricsPrefix><samplerName>.h.count | 服務器每秒命中次數(每秒點擊數,即TPS) |
| <rootMetricsPrefix><samplerName>.ok.min | sampler響應成功的最短響應時間 |
| <rootMetricsPrefix><samplerName>.ok.max | sampler響應成功的最長響應時間 |
| <rootMetricsPrefix><samplerName>.ok.avg | sampler響應成功的平均響應時間 |
| <rootMetricsPrefix><samplerName>.ok.pct<percentileValue> | sampler響應成功的所占百分比 |
| <rootMetricsPrefix><samplerName>.ko.count | sampler的失敗響應數 |
| <rootMetricsPrefix><samplerName>.ko.min | sampler響應失敗的最短響應時間 |
| <rootMetricsPrefix><samplerName>.ko.max | sampler響應失敗的最長響應時間 |
| <rootMetricsPrefix><samplerName>.ko.avg | sampler響應失敗的平均響應時間 |
| <rootMetricsPrefix><samplerName>.ko.pct<percentileValue> | sampler響應失敗的所占百分比 |
| <rootMetricsPrefix><samplerName>.a.count | sampler響應數(ok.count+ko.count) |
| <rootMetricsPrefix><samplerName>.sb.bytes | 已發送字節 |
| <rootMetricsPrefix><samplerName>.rb.bytes | 已接收字節 |
| <rootMetricsPrefix><samplerName>.a.min | sampler響應的最短響應時間 (ok.count和ko.count的最小值) |
| <rootMetricsPrefix><samplerName>.a.max | sampler響應的最長響應時間 (ok.count和ko.count的最大值) |
| <rootMetricsPrefix><samplerName>.a.avg | sampler響應的平均響應時間 (ok.count和ko.count的平均值) |
| <rootMetricsPrefix><samplerName>.a.pct<percentileValue> | sampler響應的百分比 (根據成功和失敗的總數來計算) |
不知道大家是否有個疑問,為何 a.min 、 a.max 、 a.avg 明明說的都是平均響應時間,但是括號里備注的又是和響應數相關的;但是Jmeter官方文檔說明翻譯過來的確是這樣的..只能等我來尋找答案了!
經過我的“縝密”對比,可以發現官網說明的確是錯的哈,真實情況如下!
a.min :是ok.min和ko.min的最小值
a.max :是ok.max和ko.max的最小值
a.avg :是ok.avg和ko.avg的平均值
接下來就是用數據說明事實!按照上面的指標順序來看圖哈!


不過,博主並不確定這樣比對是否完全科學正確,但是從博主驗證結果來說,我的糾正是正確滴!
附上按官方文檔說明翻譯過來的對比圖,可以看到如果是 a.max 的話,跟 ok.count 和 ko.count 是沒有半毛錢關系的

配置Grafana
首先進入Grafana的首頁,可以看到官方畫了個流程:先創建數據源,再創建數據面板

創建數據源
一共有兩個入口哈,可以在首頁直接點擊 Create your first data source ,也可以看第二張圖按步驟進入創建頁面


然后,選擇InfluxDB作為我們的數據源



到此為止,數據源就配置成功啦!!
配置數據看板

Grafana&InfluxDB集成,展示測試結果數據
panel基礎使用
按上面的步驟創建好DashBoard后,再通過panel展示具體數據,先介紹下panel的入口

一般選 Add Query 先,當然選 Choose Visualization 也可以,進去后可以相互切換的
Convert to row 就是生成一行,可以將展示差不多一致類型數據的panel放到里面,統一管理,收起or展開;
如下圖,我將描述線程數和響應數的panel放在同一個Row了

數據綁定
查看總線程數、成功響應數、失敗響應數
可以先點Add Query,進入到下面的界面

若想看成功響應數和失敗響應數,只需要切換表名即可;
可以發現跟我一開始只展示數字不太一樣,因為圖表類型還沒設置;當我們只想看數據而不想看數據趨勢圖的話,可以改變它的類型;
在同一個界面,點擊左側列表選中第二個icon,然后選擇Singlestat即可

查看所有請求、get請求、post請求的TPS
如果想在同一個panel里展示多個指標數據的話,可以通過在Panel里Add Query

基本的數據綁定已經教會大家啦,自己想要展示什么數據直接改變表名就行了
順帶附上官方提供的一個數據看板圖,大家也可以照搬照抄用它的panel,手動添加每個指標

至此,初級版的Grafana+Jmeter+Influxdb 性能實時監控平台初步搭好啦!
當然博主是不建議Jmeter使用 GraphiteBackendListenerClient 來采集數據的,因為請求多起來的時候會有非常多的表,維護成本也會增加;后面將會介紹如何通過 InfluxDBBackendListenerClient 來采集數據
配置Backend Listener之InfluxDBBackendListenerClient
配置項含義

首先來看看每個配置項的含義
- influxdbUrl:安裝influxdb的路徑;主要格式:http://主機地址:8086/write?db=數據庫名
- application:應用名稱;在 events 表中對應的字段是 application
- measurement:表名;數據存儲到哪個表,默認是jmeter,不用改即可
- summaryOnly:同GraphiteBackendListenerClient
- samplersRegex:同GraphiteBackendListenerClient
- percentiles:同GraphiteBackendListenerClient
- testTitle:測試名稱;在 events 表中對應的字段是 text ,JMeter在測試的開始和結束時自動生成注釋,該注釋的值以'start'和'end'結尾
- eventTags:Grafana允許為每個注釋顯示標簽;在 events 表中對應的字段是 tags
不懂application和testTitle的小伙伴可以看看下面的圖,可以看到同一個testTitle的兩條記錄的時間差就是執行測試計划的總時長

建議:只需修改application和testTitle即可,可以相同也可以不相同,其他配置跟着圖片走就好了;當然安裝路徑還是要改的哈
查看InfluxDB
使用InfluxDBBackendListenerClient好處就是,再多的請求也只會生成兩張表:

events :主要拿存事件的
jmeter :存測試結果數據的,Grafana也是從這個表獲取數據再展示
再次Grafana&InfluxDB集成,展示測試結果數據
這次就不再需要自己去創建DashBoard和Panel了,因為在官方模板庫,已經有一個非常完美的模板了,當然前提是你要用 InfluxDBBackendListenerClient 采集數據才能有效的哈
首先,進入官方模板庫: https://grafana.com/dashboards ,然后跟着圖片導入模板並初始化即可


只要你的數據源,表名配的沒有錯,Jmeter再執行一下測試計划,DashBoard中篩選下時間,就可以成功看到數據啦!

模板自帶了三個下拉篩選框
data_source:數據源,在Grafana配置了多少個就顯示多少個
application:在Jmeter配置好的application,如果每次測試計划執行時的application都不一樣,你就可以通過這個篩選出對應測試時機的結果數據了
transaction:在Jmeter配置好的sampleList,譬如我只發了get、post請求,這里就只會給你選get、post;可以滑到頁面下面看到針對某個請求的數據展示
其實這個模板還有很多可以值得改進優化的地方,辣么這個時候就需要你對Grafana的各種用法熟悉操作啦,后續會補充一篇關於Grafana常見用法&高級用法的文章哦!敬請期待!
