1.前言
在使用jmeter做性能測試的時候,監控系統性能的時候,無論是使用插件還是報告生成,都沒法實現實時監控。使用JMeter+Influxdb+Grafana可以實現實時監控。
本次環境搭建各軟件版本說明:
Grafana v6.2.5
InfluxDB 1.7.0
JMeter 5.2.1
2.Influxdb簡介
InfluxDB是用Go語言編寫的高性能、高可用的分布式時序數據存儲數據庫,無其他依賴,安裝簡單快速。
該數據庫現在主要用於存儲涉及大量的時間戳數據,如DevOps監控數據,APP metrics, loT傳感器數據和實時分析數據。
InfluxDB特征:
- 無結構(無模式):可以是任意數量的列
- 可以設置metric的保存時間
- 支持與時間有關的相關函數(如min、max、sum、count、mean、median等),方便統計
- 支持存儲策略:可以用於數據的刪改。(influxDB沒有提供數據的刪除與修改方法)
- 支持連續查詢:是數據庫中自動定時啟動的一組語句,和存儲策略搭配可以降低InfluxDB的系統占用量。
- 原生的HTTP支持,內置HTTP API
- 支持類似sql語法select * from mysql.user
- 支持設置數據在集群中的副本數
- 支持定期采樣數據,寫入另外的measurement,方便分粒度存儲數據。
schemaless: 結構型數據庫類似Mysql需要先定義列,influxdb無需預先定義,無結構的
與傳統數據庫中的名詞比較
influxDB中的名詞 | 傳統數據庫的概念 |
database | 數據庫 |
measurement | 數據庫中的表 |
points | 表里面的一行數據 |
influxdb的points數據說明
- time:默認存儲數據會有時間,時間無需關心,會幫我們自動插入
- tags:用來存儲數據標識,比如CPU.idle
- fileds:用來存儲數據 value=90
3.下載
定位到/usr/local目錄下,執行命令:wget https://dl.influxdata.com/influxdb/releases/influxdb-1.7.0.x86_64.rpm --no-check-certificate,然后等待下載完成
4.解壓安裝
執行命令:rpm -ivh influxdb-1.7.0.x86_64.rpm
安裝完之后,生成默認的配置文件 /etc/influxdb/influxdb.conf,可以到/ect目錄下去查看
5.修改influxDB配置文件
執行命令:vi /etc/influxdb/influxdb.conf,將最終修改的配置如下:
[[graphite]]
# Determines whether the graphite endpoint is enabled. enabled = true database = "jmeter" # 數據庫名稱 retention-policy = "" bind-address = ":2003" # 端口 protocol = "tcp" consistency-level = "one" 修改以下信息 [meta] dir = "/usr/local/influxdb/meta" #存放最終存儲的數據,文件以.tsm結尾 [data] dir = "/usr/local/influxdb/data" #存放數據庫元數據 wal wal-dir = "/usr/local/influxdb/wal" #存放預寫日志文件 修改HTTP端口信息 [http] # Determines whether HTTP endpoint is enabled. enabled = true # The bind address used by the HTTP service. bind-address = ":8086"
修改完成后執行:wq保存退出
6.在上一步中我們設置了存放數據的目錄為/usr/local/influxdb,這個目錄不會自動生成,因此需要手動創建並授權,執行命令如下:
我這里使用的是root用戶,使用其他用戶如果報權限不足則需要切換到root用戶
7.啟動influxDB服務
啟動influxDB服務有兩種方式:
方式一: 直接執行命令: influxd -config /etc/influxdb/influxdb.conf
啟動后顯示如下圖:
方式二(推薦):
-bash-4.2# vi /etc/profile
添加變量:export INFLUXDB_CONFIG_PATH=/etc/influxdb/influxdb.conf,然后保存,如下圖:
執行:source /etc/profile,是配置文件生效后,執行:influxd &,啟動
influxDB的tcp端口是8088,執行:netstat -antp|grep 8088,顯示如下則表示端口啟動成功
8.創建數據庫及用戶
執行命令如下:
-bash-4.2$ influx
> show databases
> CREATE DATABASE jmeter
> use jmeter
> create user "admin" with password '123456' with all privileges
此處設置的用戶名和密碼需要記錄下來,后面配置JMeter和Grafana時有用到
注:這里要注意一下,CREATE DATABASE必須使用大寫
網上有使用小寫創建數據庫,如:create databases "jmeter",執行后會報錯,報錯信息如下
ERR: error parsing query: found DATABASES, expected CONTINUOUS, DATABASE, USER, RETENTION, SUBSCRIPTION at line 1, char 8
Warning: It is possible this error is due to not setting a database.
Please set a database with the command "use <database>".
端口說明:
2003端口:Jmeter往數據庫發數據的端口,服務器端也是該端口接收數據,所以如果使用雲服務器ECS的話,需要開啟該2003端口
8086端口,Grafana從數據庫取數據的端口
9.JMeter配置
新建一個測試計划,新建一個線程組,右鍵測試計划選擇Add->Listener->Backend Listener,如果使用的是中文則添加后端監聽器的路徑是:右鍵測試計划選擇添加->監聽器->后端監聽器
添加后端監聽器,配置如下圖:
新建請求,然后執行
10.在服務器上查看influxdb是否有接收數據成功:
執行如下命令:
-bash-4.2$ influx
> show databases
> use jmeter
> show measurements
11. 安裝配置grafana
下載安裝:
#下載 wget https://dl.grafana.com/oss/release/grafana-6.2.5-1.x86_64.rpm #安裝 sudo yum localinstall grafana-6.2.5-1.x86_64.rpm #添加到服務並自啟動 /sbin/chkconfig --add grafana-server systemctl enable grafana-server.service #啟動服務 service grafana-server start #查看安裝 find / -name grafana
grafana默認啟動3000端口,可以使用netstat -antp | grep 3000 ,確認端口是否啟動,端口啟動后可通過一下地址訪問Grafana: 服務器IP地址:3000
會展示默認的登錄界面,默認用戶名密碼都是admin,登錄進去后如下圖
配置數據庫:
選擇InfluxDB
最終配置如下圖,配置好后點擊下面的 Save & Test 按鈕,提示 Data source is working 就表示數據庫連接成功
接下來配置監控面板,配置panel有兩種方式:1.手動配置panel 2.在官網下載panel模板
下面先講第一種方式:
點擊左上角Grafana圖標,進入Home界面,點擊左側“+”號菜單,點擊Dashboard,
進入New dashboard界面,點擊Add Query(各個版本的顯示不一樣,但是操作流程是一樣的)
進入面板設置界面,如下圖
說明:想了解這些查詢具體是什么意思,可以訪問Jmeter的官網地址去查看 http://jmeter.apache.org/usermanual/realtime-results.html
線程數/用戶相關指標 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:采樣器響應百分比(根據和失敗樣本的總數計算) Backend Listener的默認百分位設置為“90;95;99”,即百分位數為90%,95%和99%。 Graphite使用點(“.”)去拆分的元素,這可能與十進制百分位值混淆。JMeter轉換任何此類值,用下划線(“ - ”)替換點(“.”)。例如,“99.9 ”變為“99_9 ” 默認情況下,JMeter發送在samplerName“all”下累計的所有采樣器的指標。 如果配置了 BackendListenerSamplersList,那么JMeter還會發送匹配樣本名稱的指標,前提是配置 summaryOnly=true
最終顯示結果如下:
接下來講第二種方式:模板方式
點擊左上角Grafana圖標,點擊Home,然后點擊Find dashboards on Grafana.com,會跳轉到Grafana官網,或者可以直接進入官網:https://grafana.com/grafana/dashboards?utm_source=grafana_search
左側輸入查詢模板的條件,如下圖,這里選擇比較常用的JMeter Load Test模板
下載JMeter-InfluxDB-Writer界面如下圖,這里下載的是最新版本1.2版本,點擊JMeter-InfluxDB-Writer-plugin-1.2.jar即可下載
下載完成后上傳到JMeter安裝目錄lib/ext目錄下,如下圖:
然后重啟jmeter,選擇rocks.nt.apm.jmeter.JMeterinfluxDBBackendListenerClient,輸入influxDB的host和端口,之前創建Influxdb的用戶名和密碼,然后保存。如果host默認是localhost,直接執行會報錯:Failed to connect to localhost/0:0:0:0:0:0:0:1:8086
上圖中的用戶名和密碼可以在服務器中查看,密碼是之前創建用戶的時候自己輸入的,執行命令:
influx
show users
接下來導入Grafana模板,點擊左上角Grafana Logo,點擊Home,然后選擇Import dashboard
打開的界面如下圖,這些需要填寫模板ID,模板ID獲取詳見下一步
在JMeter Load Test模板界面點擊Copy ID to Clipboard,將ID復制好然后粘貼到Grafana導入模板界面,如下圖:
輸入模板ID 1152后,點擊空白處,會顯示如下圖信息,請按照下圖中進行修改:
查看模板可以點擊左上角Grafana Logo,點擊模板名稱,這里是默認的JMeter Load Test
默認模板顯示如下圖:
重啟JMeter,執行測試,在Grafana界面的右上角選擇要顯示的時間,最終顯示壓測結果如下圖(右上角刷新時間建議選小一點,效果會比較明顯):
遇到的問題:
1.創建influxdb數據庫的時候使用create databases "jmeter",報錯
解決辦法:必須使用大寫來進行創建,命令是:CREATE DATABASE jmeter
2.執行Jmeter請求,jmeter日志報Error writing to Graphite: connect timed out,具體報錯信息如下:
2020-07-17 16:51:29,810 ERROR o.a.j.v.b.g.TextGraphiteMetricsSender: Error writing to Graphite: connect timed out
java.net.SocketTimeoutException: connect timed out
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) ~[?:1.8.0_171]
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source) ~[?:1.8.0_171]
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) ~[?:1.8.0_171]
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) ~[?:1.8.0_171]
at java.net.AbstractPlainSocketImpl.connect(Unknown Source) ~[?:1.8.0_171]
at java.net.PlainSocketImpl.connect(Unknown Source) ~[?:1.8.0_171]
at java.net.SocksSocketImpl.connect(Unknown Source) ~[?:1.8.0_171]
at java.net.Socket.connect(Unknown Source) ~[?:1.8.0_171]
at org.apache.jmeter.visualizers.backend.graphite.SocketOutputStreamPoolFactory.create(SocketOutputStreamPoolFactory.java:77) ~[ApacheJMeter_components.jar:5.2.1]
at org.apache.jmeter.visualizers.backend.graphite.SocketOutputStreamPoolFactory.makeObject(SocketOutputStreamPoolFactory.java:48) ~[ApacheJMeter_components.jar:5.2.1]
at org.apache.jmeter.visualizers.backend.graphite.SocketOutputStreamPoolFactory.makeObject(SocketOutputStreamPoolFactory.java:34) ~[ApacheJMeter_components.jar:5.2.1]
at org.apache.commons.pool2.impl.GenericKeyedObjectPool.create(GenericKeyedObjectPool.java:1041) ~[commons-pool2-2.7.0.jar:2.7.0]
at org.apache.commons.pool2.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:342) ~[commons-pool2-2.7.0.jar:2.7.0]
at org.apache.commons.pool2.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:265) ~[commons-pool2-2.7.0.jar:2.7.0]
at org.apache.jmeter.visualizers.backend.graphite.TextGraphiteMetricsSender.writeMetrics(TextGraphiteMetricsSender.java:110) [ApacheJMeter_components.jar:5.2.1]
at org.apache.jmeter.visualizers.backend.graphite.TextGraphiteMetricsSender.writeAndSendMetrics(TextGraphiteMetricsSender.java:104) [ApacheJMeter_components.jar:5.2.1]
at org.apache.jmeter.visualizers.backend.graphite.GraphiteBackendListenerClient.sendMetrics(GraphiteBackendListenerClient.java:183) [ApacheJMeter_components.jar:5.2.1]
at org.apache.jmeter.visualizers.backend.graphite.GraphiteBackendListenerClient.run(GraphiteBackendListenerClient.java:146) [ApacheJMeter_components.jar:5.2.1]
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_171]
at java.util.concurrent.FutureTask.runAndReset(Unknown Source) [?:1.8.0_171]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source) [?:1.8.0_171]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) [?:1.8.0_171]
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [?:1.8.0_171]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [?:1.8.0_171]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_171]
打開配置文件,發現enabled的值為false,需要改為true,設置結果如下圖:
修改之后還是沒有解決,因為用的是阿里雲服務器,需要去阿里雲開啟對應的端口,設置端口如下圖,我這里是外網訪問,端口一定開放公網入方向才可以,可以是內網則需要在內網入方向下開放2003端口
然后重新執行JMeter,執行一段時間后在服務器上查看influxdb的數據庫,顯示結果如下圖則表示jmeter發送數據到influxdb成功
3.Jmeter執行后查看influxdb數據庫,執行show measurements時顯示無數據
原因分析:服務器沒有打開防火牆
解決方法:
firewall-cmd --state #查看防火牆狀態,如果是running則表示防火牆已開啟,使用 sys
systemctl stop firewall.service #關閉防火牆 或者使用systemctl stop firewalld.service
systemctl start firewall.service #開啟防火牆 或者使用systemctl start firewalld.service
關閉防火牆后,在Jmeter上執行請求,然后在服務器上進入influx查看是否數據,結果如下圖則表示jmeter的數據已經推送到influxdb
排查過程:1.服務器本地查看端口8086和2003是否開啟成功,結果顯示兩個端口是開啟成功且本地可以訪問的
2.Win10上ping 服務器,可以ping通,但是端口ping不通
3.查看防火牆
參考資料:
https://www.cnblogs.com/mike-liu/p/10080351.html