1. 程式人生 > 實用技巧 >JMeter 4.0 分散式測試原理及填坑注意事項

JMeter 4.0 分散式測試原理及填坑注意事項

我們使用 JMeter 進行效能測試時,經常遇到 JMeter 假死的情況。一般有兩個原因:一是 JMeter 原本是Java寫的,heap受硬體限制需要調優,二是單機無法分解超大併發比如100萬+併發壓測。因此,我們分二部走,首先我們需要進行jmeter分散式部署和調配,二是我們需要對每臺執行機進行深度 JMeter JVM 調優,掠盡所有執行及的硬體和網路資源。

一、JMeter 分散式部署與配置

下圖為 JMeter 的原理圖,Controller 可以 GUI 模式執行,也可以非 GUI 模式執行。


JMeter 分散式原理

PS:JMeter 分散式測試注意事項:

  1. 每一臺 Slave 都執行相同的測試計劃,JMeter 不會在執行期間做負載均衡,每一臺 Slave 都會完整地執行測試計劃。
  2. Controller 和 Slave 最好分開,由於 Contoller 需要傳送資訊給 Slave,並且接收 Slave 回傳的測試結果,Controller 就會存在較大的消耗,所以建議單獨使用一臺機器作為 Controller。
  3. 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

連線不同解決辦法:

  1. 更換遠端伺服器(執行機 Slave),是 Controller 和 Slave 都處在同一網路中。

2. 機器的環境配置

  1. JMETER_HOME/bin/jmeter.properties 檔案,

    • Slave 在server_port標註埠號(可以為預設的,也可以自己新修改的), remote_hosts上寫上本機的 ip 地址和埠號,如下圖所示
    Slave remote_hosts設定
- 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)
  1. 設定 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 本身不執行測試操作。

啟動指定遠端 JMeter 客戶端執行測試

三、注意事項和坑

  1. 如果壓測指令碼需要進入外部的資料檔案,則需要當前每個 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 存放的路徑需要一致。推薦使用相對路徑存放資料檔案。

  2. 出現以下錯誤資訊,請檢視Slave 的 jmeter-server 服務是否已開啟。

    遠端拒絕資訊
  1. 如果出現以下錯誤資訊,請對Slave 的 jmeter-server 重啟。以下錯誤資訊可能是缺失資料檔案引起的。

    Engine is busy
  1. 如果 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
  1. 直接執行./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
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。