如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

博為峰網校發表於2019-08-08

JMeter是當前Web效能測試中應用最為廣泛的工具,簡潔強大的介面,開源免費的授權,以及廣泛的外掛擴充套件,使得JMeter能滿足幾乎所有Web場景的效能測試。然而,單機效能的限制,是JMeter一直以來最大的詬病。

由於採用Java多執行緒進行併發使用者的模擬,使得執行緒數的增加自然增加了測試機的資源消耗。一邊是被測系統併發數的日益提高,一邊是JMeter單機效能的掣肘。測試人員彷彿是走鋼絲的雜技演員,平衡木的一邊是併發數,一邊是測試機的資源,戰戰兢兢、小心謹慎的想找到其中的平衡。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

實際上JMeter提供了一種分散式壓測的方法提高併發能力。本文介紹如何配置一個JMeter的分散式測試環境,並對單機和分散式的測試機資源佔用情況進行對比。最後,對分散式的執行緒數、併發機制以及影響分散式TPS的取樣資訊回送模式進行說明。

一、引入JMeter分散式

JMeter是Web效能測試中的利器,基本屬於Web壓測的事實標準。然而使用過JMeter的測試人員會發現,當併發使用者增加後,JMeter本身的效能也會急劇下降,導致無法對被測系統施加壓力。

以一個實際環境為例,系統配置為:Windows 7旗艦版,i5-4590單CPU4核4執行緒,4G記憶體。使用JMeter3.1,Java8進行測試。

當併發執行緒設定為1000時,資源佔用如下圖。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

繼續增加執行緒個數為1500,此時執行出現錯誤如下。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

檢視日誌中的記錄,可以看到由於記憶體不足,無法啟動新的執行緒。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

如果我們需要更多的執行緒併發,此時就必須使用JMeter的分散式壓測了。

二、環境搭建

遵照JMeter官網的方法,很容易搭建適合自己需要的分散式環境。以下圖的實際環境為例,測試機A作為壓測的協調主機(即上述的機器),B和C作為執行機,實際完成壓力的傳送,被測系統位於D上。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

具體配置過程如下:

1、執行機屬性配置。配置執行機RMI服務的埠,修改\apache-jmeter-3.1\bin下的jmeter.properties,將如下屬性修改為指定的埠:server_port和server.rmi.localport。本例中B均修改為1039,C均修改為1058。如下圖:

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點
如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

2、啟動執行機的監聽服務。在執行機上啟動服務,開啟\apache-jmeter-3.1\bin下的jmeter-server.bat即可。啟動圖如下。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點
如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

說明在B的1039埠,C的1058埠均啟動了執行的服務,等待協調主機的命令。

3、協調主機屬性配置。配置協調主機連線的執行機和埠,修改\apache-jmeter-3.1\bin下的jmeter.properties,將remote_hosts屬性修改為需要連線的執行機IP和埠。如下圖。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

4、執行測試。啟動協調主機的JMeter,透過介面進行啟動。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

如上圖,透過Run->Remote Start可以啟動單個執行機,透過Remote Start All啟動全部執行機。

三、資源對比

在前面我們看到,單臺如上配置的測試機在啟動1500執行緒時會出現記憶體不夠用的情況。那麼分散式的情況如何呢?

下圖為協調主機的資源佔用情況。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

其中一臺執行機的資源佔用情況,執行機B,Windows10 教育版,i5-6500單CPU4核心4執行緒(3.20GHz),8G記憶體。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

另外一臺執行機的資源佔用情況,執行機C,配置為Windows Server 2012 R2 Standard,Intel Xeon單CPU6核12執行緒。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

四、注意事項

透過JMeter分散式進行壓測,可以避免單機測試機資源的限制,提高壓測的併發執行緒數。然而,還有一些細節需要注意。

1)執行緒數

JMeter分散式測試,是透過網路連線將協調主機載入的指令碼分別傳遞(複製)給執行機,也就是說每個執行機拿到的指令碼都是一致的,所以在每臺執行機都會啟動指令碼中執行緒組指定的併發執行緒數。這樣在設定指令碼執行緒數目時,需要除以執行機個數,設定併發執行緒數。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

以上述示例進行說明,期望完成1500使用者併發,在單機測試時指令碼設定併發執行緒為1500,而在有兩條執行機的情況下需要設定為750,指令碼修改如下。

此時啟動遠端測試Remote Start All後,看到介面的顯示如下。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

其中的1500/0,含義是一共啟動了1500個執行緒,本機為0。

2)同步定時器的使用

我們知道,同步定時器(Synchronizing Timer)的意義在於提供瞬間壓力的測試,其原理是阻塞期望個數的執行緒(使用者),在同時進行釋放,儘可能真實的模擬併發使用者同時進行某操作的情況。那麼在分散式併發的情況是如何的呢?我們將上述例子簡化為20使用者併發,即每個執行機10個執行緒,同時增加一個同步定時器,期望15個執行緒瞬間壓測。指令碼修改如下。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

執行遠端測試Remote Start All,監控結果樹的情況。會發現沒有任何請求被髮送。這是因為,同步定時器僅在一個JVM中起作用,而分散式環境下屬於兩臺機器的兩個獨立JVM,同步定時器無法生效。此時對於每個執行機,均啟動了10個執行緒,但獲得的指令碼中需要等待20個執行緒再釋放,所以兩個執行機均不會向下執行。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

JMeter官網原文如上,含義就是同步定時器阻塞執行緒的機制僅在一個JVM中,所以在分散式的情況下,設定的阻塞執行緒數不能超過每個執行機的併發執行緒數。本例中就是不能超過10執行緒。

類似的,高斯隨機定時器(Gaussian Random Timer),固定定時器(Constant Timer),均勻隨機定時器(Uniform Random Timer),泊松隨機定時器(Poisson Random Timer),BeanShell定時器,BSF定時器,JSR定時器。由於是針對單執行緒的,所以不受分散式的影響。

當然,吞吐量定時器也是對於每個執行機獨立進行限制的。也就是說,設定的吞吐量限定值,由於指令碼是分別在每個執行機進行執行的,所以限定的也都是當前作用的執行機。

3)執行機測試結果回送方式

JMeter分散式的原理十分容易理解,在實際測試中就如同蝴蝶效應一樣,一點細微的差別都會導致最終加壓結果的巨大差異,從而導致最終測試結果的不確定性。在分散式測試中,執行機測試結果的回送方式影響非常大。

首先我們對比一下實際的測試結果。在協調主機和執行機上的配置檔案\apache-jmeter-3.1\bin下的jmeter.propertie中,修改mode=StrippedBatch,如下截圖。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

注意在協調主機和執行機上均要修改。執行測試,此時我們檢視協調主機的網路使用率和測試的TPS,可以發現對於百兆網路卡使用了其中7%的流量,對於被測系統的TPS為461。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

此時檢視其中一個執行機的網路使用情況,也在可以接收的範圍內。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

接下來,修改mode=Standard,進行同樣的測試。觀察協調主機的測試結果如下。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

可以看到100M網路卡已經被消耗殆盡,使用率達到97.3%,而TPS也只有92,可以想象,此時對被測系統壓力是非常有限的。同樣的,可以看到執行機的網路使用情況如下。

如何將bug殺死在搖籃裡?解讀壓測必經之路JMeter分散式的技術點

對比之前的結果,也是讓人堪憂的。可以想象,以這樣的測試環境對被測系統進行測試,得到的測試結果能有多大的可信度。

JMeter官網有非常具體的描述,主要內容如下。指令碼中的監聽器會根據配置將測試結果回傳,預設情況下當結果產生後同步回傳到協調主機。這會影響測試的最大吞吐量,JMeter提供了配置屬性對此進行干預,即jmeter.propertie檔案中的mode屬性。 該屬性可以有如下取值:

1)Standard:測試中的取樣資訊產生的同時回傳給協調主機。

2)Hold:在測試結束前將取樣資訊儲存在陣列中。這種模式會佔用執行機大量記憶體,不推薦使用。

3)DiskStore:在測試結束前,將結果儲存在硬碟檔案(由java.io.temp屬性指定)中。這種序列化檔案會在JVM退出後刪除。

4)StrippedDiskStore:將成功的響應資料在取樣資訊中刪除,之後使用DiskStore的方式處理。

5)Batch:當取樣資訊超過指定的閾值後,同步將取樣資訊傳送。閾值可以是取樣個數閾值(num_sample_threshold)或者時間(time_threshold),這兩個閾值可以在執行機的jmeter.propertie檔案中指定。

num_sample_threshold:累加的取樣個數,預設為100。

time_threshold:時間閾值,預設為60000ms(即60秒)。

後面的Asynch模式與該模式類似。

6)Statistical:當取樣資訊超過指定閾值後,傳送取樣資訊的摘要資訊。根據執行緒組和取樣名稱進行表記。摘要包括如下欄位:

Elapsed time:流逝時間

Latency:延遲

Bytes:位元組

Sample count:取樣個數

Error count:錯誤個數

其他欄位會被丟棄。(5)中的兩個屬性也對該模式起作用。

7)Stripped:將成功的取樣在響應資料中刪除。

8)StrippedBatch:在響應資料中刪除成功取樣後,使用Batch模式。

9)Asynch:取樣資訊在本地佇列中臨時儲存。啟動一個獨立的工作執行緒進行取樣資訊傳送。這樣能夠允許測試執行緒得以持續執行而不用等待回送的結果返回。當然,當結果產出太快,導致臨時佇列被充滿,也會使得測試執行緒阻塞,直到佇列中一些資料排空。該模式可以用來削平取樣資訊的網路波峰。透過執行機JMeter的屬性asynch.batch.queue.size?(預設100)進行佇列大小配置。

10)StrippedAsynch:在響應資料中刪除成功取樣,再使用Asynch模式。

11)自定義:透過配置一個特定的Java類,可以配置自行擴充套件的傳送模式。擴充套件類必須首先介面SampleSender,並且實現接收一個具有RemoteSampleListener型別變數的建構函式。

上述提到的Stripped類的模式,都會將響應資料中的成功資訊進行刪除,所以一些依賴前置響應資料的元件會出現問題。這個問題可以透過調整測試指令碼得以解決。

加我VX:ww-51testing   回覆關鍵詞“測試”領取限量軟體測試學習資料哦~~

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31407649/viewspace-2653098/,如需轉載,請註明出處,否則將追究法律責任。

相關文章