1、JMeter分散式測試概念
(1)什麼是分散式測試
分散式測試是指通過區域網和Internet,把分佈於不同地點、獨立完成特定功能的測試計算機連線起來,以達到測試資源共享、分散操作、集中管理、協同工作、負載均衡、測試過程監控等目的的計算機網路測試。
即:由多臺電腦共同完成同一個測試計劃的執行,我們稱這種測試的方式為分散式測試。換句話說,也就是一個人幹不了,就多叫幾個人一起幹。
(2)為什麼要使用分散式測試
在工作中使用JMeter做大併發壓力測試的場景下,需要模擬成百上千的使用者併發,這樣使用單臺機器模擬所有的併發使用者就有些力不從心。
因為單機受限記憶體、CPU、網路IO等,會出現被測伺服器壓力還沒有上去,但是執行壓測的伺服器已經由於模擬的壓力太大而當機了。
為了讓JMeter工具能夠提供更強大的負載能力,JMeter提供了多臺機器同時產生負載的機制,也就是我們所說的分散式的執行方式。
即:JMeter的叢集模式可以讓我們將多臺機器聯合起來一起產生負載,從而彌補單臺機器負載生成能力不足的問題。
JMeter自身的侷限性總結:
- 由於一臺電腦的CPU、記憶體有限,無法滿足更高的測試要求。一臺壓力機中的JMeter,預設最大支援 1000 左右的併發使用者數(執行緒數),再大的話,容易造成卡頓、無響應等情況。
- 由於 JMeter是 Java 應用,對 CPU 和記憶體的消耗較大,在需要模擬大量併發使用者數時,單機很容易出現 JAVA 記憶體溢位的錯誤,導致測試指令碼本身就有瓶頸。
(3)JMeter分散式測試原理
- 一臺電腦作為控制機(
Controller
、master
),其它電腦做為執行機(Agent
、slave
)。 - JMeter指令碼執行時,控制機會把指令碼傳送到每臺執行機上,執行機拿到指令碼後就開始執行。
- 在執行機中執行指令碼時,不需要啟動JMeter工具介面,可以理解它是通過命令列模式執行的。
- 執行完成後,執行機會把結果回傳給控制機,控制機會收集所有執行機的資訊並彙總。
JMeter分散式測試架構圖如下:
說明:
假設我們的測試計劃會產生100個
threads
,我們使用8臺機器進行分散式測試的時候,一共會產生100 * 8 = 800的負載。
2、JMeter分散式測試前提條件
所有機器,包括master
和slave
機器:
- 執行相同版本的JMeter。
- 使用相同版本的Java環境,即JDK。
- 所有機器都要在一個網路中。即:同一區域網中,也就是同一網段中。
- 有基於SSL的RMI的有效金鑰庫,或者禁用SSL。(本文舉例中都是採用的禁用SSL)
即:在jmeter.properties
配置檔案中,配置server.rmi.ssl.disable=true
。 - 關閉防火牆,尤其是Linux系統。
提示:
Agent
機器上可以不放JMeter的指令碼,但如果有用到測試資料,就必須把測試資料放到Agent
機器上去。Controller
和Agent
機器上最好裝有相同版本的JDK和JMeter,並配置好環境變數。
3、JMeter實現分散式測試
環境說明:
- 準備四臺電腦:
兩臺Windows系統的電腦:192.168.1.101
、192.168.1.102
兩臺Linux系統電腦:192.168.1.103
、192.168.1.104
- Java環境:JDK 1.8
- JMeter版本:5.4.1
提示:
- 設定
192.168.1.101
為控制機(Controller
、master
)。- 設定
192.168.1.102
、192.168.1.103
、192.168.1.104
為執行機(Agent
、slave
)。
(1)在執行機中的配置
修改JMeter的bin
目錄中jmeter.properties
檔案。
remote_hosts=127.0.0.1
server_port=9996
# 禁用ssl
server.rmi.ssl.disable=true
如下圖所示:
提示:Linux系統中,在VIM編輯使用末行命令
/
,可以搜尋目錄文字的位置。(後面不再重複說明了)
三臺執行機都進行如上的配置:
192.168.1.102
:remote_hosts:127.0.0.1
、server_port:9996
。192.168.1.103
:remote_hosts:127.0.0.1
、server_port:9996
。192.168.1.104
:remote_hosts:127.0.0.1
、server_port:9996
。
(2)在控制機中的配置
修改JMeter的bin
目錄中jmeter.properties
檔案。
# 配置slaves機器的ip和埠
remote_hosts=192.168.1.102:9996,192.168.1.103:9996,192.168.1.104:9996
# 禁用ssl
server.rmi.ssl.disable=true
如下圖所示:
提示:不同壓力機埠可以不一樣,不需要全部都一致。
如果控制機也需要作為測試機,配置如下:
# 配置slaves機器的ip和埠
remote_hosts=192.168.1.102:9996,192.168.1.103:9996,192.168.1.104:9996,192.168.1.101:9996
# 向外暴露的埠
server_port=9996
# 禁用ssl
server.rmi.ssl.disable=true
(3)啟動執行機中的JMeter服務
我們在所有需要執行JMeter指令碼的執行機上,啟動jmeter-server
服務。
進入到JMeter安裝路徑的bin
目錄中,執行命令:./jmeter-server
。
如下所示:
# 啟動jmeter服務
# 正常啟動後會提示"created remote object";
[root@jmeter-01 bin]# ./jmeter-server
Created remote object: UnicastServerRef2 [liveRef: [endpoint:[192.168.134.130:44502](local),objID:[-5443769e:179e1ccce1a:-7fff, -3275396589838068571]]]
提示:
- 在Windows系統中,是直接啟動
bin\jmeter-server.bat
檔案。- 如果控制機也需要執行測試,同樣也需要啟動
jmeter-server
服務。
執行機中執行測試計劃會出現Starting the test
和Finished the test
字樣。
如下所示:
[root@jmeter-01 bin]# ./jmeter-server
Created remote object: UnicastServerRef2 [liveRef: [endpoint:[192.168.134.130:44502](local),objID:[-5443769e:179e1ccce1a:-7fff, -3275396589838068571]]]
Starting the test on host 192.168.134.130:9996 @ Sun Jun 06 22:50:32 CST 2021 (1622991032238)
Finished the test on host 192.168.134.130:9996 @ Sun Jun 06 22:52:46 CST 2021 (1622991166865)
(4)在控制機中執行JMeter測試指令碼
因為我的控制機是一臺Windows系統的電腦,我們可以使用GUI的方式進行演示。
1)我們先來使用一臺遠端執行機執行我們的本地指令碼。
在JMeter中操作:執行 —> 遠端啟動 —> 選擇一個遠端執行機
,則控制機中的指令碼,會自動傳送到遠端執行機上進行執行。
如下圖所示:
提示:這裡會顯示所有
remote_hosts
新增的壓力機。
指令碼執行完成,控制機中收到的結果如下所示:
2)我們使用三臺遠端執行機執行我們的本地指令碼。
在JMeter中操作:執行 —> 遠端啟動所有
,如下圖所示:
指令碼執行完成,控制機中收到的結果如下所示:
我們可以看到,每臺執行機執行50次請求,三臺執行機就能生成出150個模擬使用者的訪問壓力。
說明:
分散式測試總樣本數 = 執行緒數 * 迴圈次數 * 執行機總數。
樣本計數邏輯為:執行機
slave
執行的測試指令碼是由排程機master
分發的,故每臺執行機執行的測試指令碼都是相同的。故而效能測試總樣本數 = 測試指令碼樣本數 * 執行機總數,而測試指令碼樣本數為執行緒數 * 迴圈次數。
以上就是使用JMeter分散式測試的全部過程。
4、Linux系統作為控制機
步驟和Windows系統作為控制機操作基本相同。
我們需要先把編輯好的JMeter測試指令碼,上傳到Linux系統的控制機中。
說明:
- 因為我們配置了JMeter的環境變數,所以可以在任何目錄中執行JMeter命令。
- JMeter測試指令碼可以放在任何目錄中來執行,不一定非要放在
bin
目錄中。- JMeter測試指令碼只需要上傳到控制機中,其他執行機上可以不放JMeter測試指令碼,因為控制機啟動後會拷貝本地的
.jmx
指令碼檔案,到遠端執行機上。- 但如果有用到測試資料,就必須把測試資料檔案放到
slave
機器上去。
我把JMeter測試指令碼上傳到tmp
目錄中,主要是找個空閒的目錄進行演示。
/tmp/jmeterscript
:存放JMeter指令碼。/tmp/jmeterlog
:存放JMeter日誌。/tmp/result
:存放測試執行結果。/tmp/resultforHTML
:存放HTML圖形化報表。
在任何路徑下執行如下命令即可:
jmeter -n -t /tmp/jmeterscript/CLI_test.jmx -r -l /tmp/result/result.jtl -j /tmp/jmeterlog/test.log -e -o /tmp/resultforHTML/tableResult
提示:
我開始使用三臺Linux虛擬機器進行操作,使用其中一臺做控制機,其他兩臺做執行機。然後我用Windows系統做控制機,起三臺Linux虛擬機器做執行機,發現都不能成功。
這是因為都是在我本地的一臺機器上啟動的這些測試機。因為網路卡的識別問題,造成啟動
jmeter-server
服務識別的控制機的網路卡不對,控制機始終收不到執行機返回來的結果。而我在另一臺電腦中啟動所有的執行機,把控制機的虛擬網路卡禁用掉,就能成功進行分散式測試。
不過不用擔心,在實際的工作中,公司會有很多的雲伺服器,不太會遇到這樣的情況。
這裡就簡單的描述一下,後面我會總結,我學習JMeter分散式測試中,遇到的所有的坑。
5、分散式測試總結
對分散式測試而言,測試過程是一種對流程控制要求很高的活動,因此係統需要適時地獲取全域性狀態以正確地指導流程。其次,在測試過程中,系統要能夠方便地監視和操縱測試過程。因此,分散式測試系統適合採用集中式的分散式策略,即,由一臺中心計算機控制若干臺受控計算機的執行,整個測試過程和資源管理由中心來完成,它掌握整個分散式測試環境的狀態,從而發出控制命令。
提示:在進行分散式測試的時候,儘量使用Linux系統,因為對測試結果的影響更少。
最後在配一個JMeter分散式測試架構圖: