JMeter 4.0 分散式測試原理及填坑注意事項
我們使用 JMeter 進行效能測試時,經常遇到 JMeter 假死的情況。一般有兩個原因:一是 JMeter 原本是Java寫的,heap受硬體限制需要調優,二是單機無法分解超大併發比如100萬+併發壓測。因此,我們分二部走,首先我們需要進行jmeter分散式部署和調配,二是我們需要對每臺執行機進行深度 JMeter JVM 調優,掠盡所有執行及的硬體和網路資源。
一、JMeter 分散式部署與配置
下圖為 JMeter 的原理圖,Controller 可以 GUI 模式執行,也可以非 GUI 模式執行。
JMeter 分散式原理
PS:JMeter 分散式測試注意事項:
- 每一臺 Slave 都執行相同的測試計劃,JMeter 不會在執行期間做負載均衡,每一臺 Slave 都會完整地執行測試計劃。
- Controller 和 Slave 最好分開,由於 Contoller 需要傳送資訊給 Slave,並且接收 Slave 回傳的測試結果,Controller 就會存在較大的消耗,所以建議單獨使用一臺機器作為 Controller。
- Controller 和所有的 Slave 都需要運行同一版本的 JDK 和 JMeter,安裝相同的外掛且版本一致(最好就是直接將 Controller 的 JMeter 直接複製一份到 Slave 上),如果版本不一致,可能會發生意外的問題;
1. 確保 Controller 和 Slave 之間的網路通訊是互通的。
這是首要條件,JMeter 的 Controller 與 Slave 之間的連線也是通過網路通訊連線起來的。如果網路通訊不同,怎麼連線、怎麼配置都會失敗,搞得你一臉懵逼。
方法:ping 一下對方的 IP 地址,看是否連通。如果連通,如下所示
~ » ping 132.16.17.58
PING 132.16.17.58 (132.16.17.58): 56 data bytes
64 bytes from 132.16.17.58: icmp_seq=0 ttl=64 time=0.088 ms
64 bytes from 132.16.17.58: icmp_seq=1 ttl=64 time=0.108 ms
64 bytes from 132.16.17.58: icmp_seq=2 ttl=64 time=0.103 ms
64 bytes from 132.16.17.58: icmp_seq=3 ttl=64 time=0.098 ms
^C
# 以下內容是按 Ctrl + C 中斷後,才顯示的內容
--- 132.16.17.58 ping statistics ---
9 packets transmitted, 9 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.066/0.097/0.124/0.019 ms
如果出現以下內容,說明單方向是不連通的。
$ ping 132.16.17.58
PING 132.16.17.58 (132.16.17.58) 56(84) bytes of data.
^C
# 以下內容是按 Ctrl + C 中斷後,才顯示的內容
--- 132.16.17.58 ping statistics ---
16 packets transmitted, 0 received, 100% packet loss, time 14999ms
連線不同解決辦法:
- 更換遠端伺服器(執行機 Slave),是 Controller 和 Slave 都處在同一網路中。
2. 機器的環境配置
-
在
JMETER_HOME/bin/jmeter.properties
檔案,- Slave 在
server_port
標註埠號(可以為預設的,也可以自己新修改的),remote_hosts
上寫上本機的 ip 地址和埠號,如下圖所示
- Slave 在
- Controller 在`server_port`標註埠號(可以為預設的,也可以自己新修改的), `remote_hosts`上寫上本機的 ip 地址和埠號,如下圖所示
![Controller r�emote_hosts設定](https://upload-images.jianshu.io/upload_images/6559549-0f78f0f1274f8366.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 設定 SSL 為 disable,
server.rmi.ssl.disable=true
,如下圖所示
SSL
PS:這個設定,在 Controller 和 Slave 都需要進行設定,缺一不可。
2.1 4.0版本新增設定 keystore
4.0版本官方幫助文件有以下這句話:
Since JMeter 4.0 the default transport mechanism for RMI will use SSL. SSL needs keys and certificates to work. You will have to create those keys yourself.
在4.0以後的版本,需要先設定 keystore 才能正常進行分散式測試,不然會報以下錯誤:
$ ./jmeter-server
Server failed to start: java.rmi.server.ExportException: Listen failed on port: 0; nested exception is:
java.io.FileNotFoundException: rmi_keystore.jks (No such file or directory)
An error occurred: Listen failed on port: 0; nested exception is:
java.io.FileNotFoundException: rmi_keystore.jks (No such file or directory)
# 直接提示沒有 rmi_keystore.jks 檔案存在
在 Controller 的 JMETER_HOME/bin/
路徑,Windows 系統執行create-rmi-keystore.bat
,Unix 系統(包含 Linux,macOS)執行create-rmi-keystore.sh
。
當您執行該指令碼時,它將詢問您一些關於它將嵌入到證書中的一些名稱的問題。您可以輸入任何您想要的內容,只要keystore工具能接受它。第一個問題輸入的值必須與屬性server.rmi.ssl.keystore匹配,預設為rmi。建立 keystore 的示例如下所示。
$ cd jmeter/bin
$ ./create-rmi-keystore.sh
What is your first and last name?
[Unknown]: rmi
What is the name of your organizational unit?
[Unknown]: My unit name
What is the name of your organization?
[Unknown]: My organisation name
What is the name of your City or Locality?
[Unknown]: Your City
What is the name of your State or Province?
[Unknown]: Your State
What is the two-letter country code for this unit?
[Unknown]: XY
Is CN=rmi, OU=My unit name, O=My organisation name, L=Your City, ST=Your State, C=XY correct?
[no]: yes
Copy the generated rmi_keystore.jks to jmeter/bin folder or reference it in property 'server.rmi.ssl.keystore.file'
以上步驟完成後,將rmi_keystore.jks
複製到所有 Slave 的JMETER_HOME/bin/
路徑。
二、分散式執行測試
Controller 和 Slave 的機器配置好了。先在 Slave 啟動 jmeter-server
指令碼,WIndows 系統執行 JMETER_HOME/bin/jmeter-server.bat
,Unix 系統執行 JMETER_HOME/bin/jmeter-server
;Controller 啟動jmeter
指令碼,WIndows 系統執行 JMETER_HOME/bin/jmeter.bat
,Unix 系統執行 JMETER_HOME/bin/jmeter.sh
。
1. Slave 執行 jmeter-server
執行 jmeter-server,新增hostname。直接執行成功:
$ ./jmeter-server -Djava.rmi.server.hostname=132.16.17.58
Created remote object: UnicastServerRef2 [liveRef: [endpoint:[132.16.17.58:31195](local),objID:[4df82a0e:1641c5906db:-7fff, 2683355085897544019]]]
2. Controller 執行 jmeter-server
2.1 非 GUI 模式啟動
啟動所有 Slave 機命令:
jmeter -n -t script.jmx -r
啟動指定 Slave 機命令:
jmeter -n -t script.jmx -R server1,server2,…
2.2 GUI 模式啟動
啟動 JMeter 的 UI 介面後,下圖是讓指定遠端端執行測試。選擇Remote Start All
是啟動所有遠端端執行測試。Controller 本身不執行測試操作。
三、注意事項和坑
-
如果壓測指令碼需要進入外部的資料檔案,則需要當前每個 slave 機器上都有該資料檔案存在,且路徑需要設定成一樣,Slave 的主路徑為啟動 jmeter-server 指令碼的路徑。
Uncaught Exception java.lang.RuntimeException: Cannot initialize RandomCSVReader, because of error: /home/server/apache-jmeter-4.0/bin/./data/test.txt (No such file or directory). See log file for details.
在 Slave 的主路徑下,外部的資料檔案存放路徑與 Controller 存放的路徑需要一致。推薦使用相對路徑存放資料檔案。
-
出現以下錯誤資訊,請檢視Slave 的 jmeter-server 服務是否已開啟。
遠端拒絕資訊
-
如果出現以下錯誤資訊,請對Slave 的 jmeter-server 重啟。以下錯誤資訊可能是缺失資料檔案引起的。
Engine is busy
-
如果 Controller 和 Slave 沒有同時配置 ssl 為 disable,執行時,Slave 端會出現以下報錯資訊:
~ » ./jmeter -n -R 132.16.17.58:2099 -t demo.jmx -l demo.jtl
Configuring remote engine: 132.16.17.58:2099
error during JRMP connection establishment; nested exception is:
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
Failed to configure 132.16.17.58:2099
Stopping remote engines
Remote engines have been stopped
Error in NonGUIDriver java.lang.RuntimeException: Following remote engines could not be configured:[132.16.17.58:2099]
```
Controller 會出現以下錯誤資訊:
non-JRMP
-
直接執行
./jmeter-server
,出現An error occurred: Cannot start. server-am-001 is a loopback address.
報錯資訊:$ ./jmeter-server Created remote object: UnicastServerRef2 [liveRef: [endpoint:[127.0.1.1:30303](local),objID:[46b30ac2:1641b5aafad:-7fff, -2320151491530847024]]] Server failed to start: java.rmi.RemoteException: Cannot start. server-am-001 is a loopback address. An error occurred: Cannot start. server-am-001 is a loopback address.
解決辦法:指定本機 IP
./jmeter-server -Djava.rmi.server.hostname=xxx.xxx.xxx.xxx
作者:DC_ing
連結:https://www.jianshu.com/p/b24c271a148a
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。