JMeter100個執行緒竟然只模擬出1個並發

執行緒組,是說到 JMeter 會第一時間想到的東西,也是我認為 JMeter 最難理解的知識點。因為項目讓你做個壓測,首先就是要考慮並發,用 JMeter 就是用多執行緒 來模擬多並發。但在看到執行緒組編輯區的時候,選項密密麻麻,無從下手呀。本篇文章就給大家介紹 JMeter 執行緒組的玩法。

JMeter 為什麼能做性能測試

我們雖然都知道 JMeter 使用執行緒在模擬用戶,但是它到底是怎麼模擬真實場景的?為什麼它就能做性能測試?

為了解答這些疑惑,我們從最簡單的登錄壓測講起。假設新項目要上線了,需要做個壓測,看看 100 個人同時登陸系統,性能怎麼樣。

我們先不用 JMeter,先用人工來做。找 100 個人,讓這些人把自己的帳號密碼輸好後,叫一聲,登錄!他們就一起點擊登錄按鈕。

這樣就算性能測試了么?不算。而且這樣測的結果並沒有參考意義。就算我們算出了此時登錄介面響應時間是 0.5 s,那麼這 0.5 s 也不能作為 100 個人同時登陸的響應時間。學過統計學就知道,單個樣本數據是會有偏差的,在實驗中需要測量多次後取平均值,才能減少誤差。

然後我們用 JMeter 來做。設置 100 個執行緒,模擬 100 個用戶,持續 5 分鐘,讓這 100 個執行緒不停的登錄,產生成千上萬條並發請求。假如登錄比較慢或登錄失敗了,用戶肯定會不停的點,就會造成持續不斷的請求。JMeter 的執行緒也可以設置無限迭代來模擬這一情況。

測試結束後,再對所有的大量的樣本數據,進行性能分析,得出平均響應時間、TPS、吞吐量等性能指標,以評估當前配置下系統性能情況,找到性能瓶頸,為性能優化提供依據。

這就是 JMeter 能做性能測試的原因,也是性能測試的意義。

知道了為什麼,接下來講講怎麼做。如果設置不當,有可能 100 個執行緒只能產生 1 個並發請求。

JMeter 的執行緒組編輯區如下:

image-20201105162110946

Name

名稱,最好有業務意義。

Comments

注釋,可以為空。

Action to be taken after a Sampler error

執行緒組中某個執行緒的請求出錯後,該怎麼處理。有 5 個選項,Continue,Start Next Thread Loop,Stop Thread,Stop Test,Stop Test Now。

例如,假設有 1 個執行緒,包括 2 個取樣器,迭代執行 2 次:

image-20201107155802114

Continue

請求出錯後,執行緒繼續運行。

為什麼要繼續運行呢?我們在大量用戶並發時,伺服器偶爾響應錯誤是正常現象,比如伺服器由於性能問題 500,此時出錯我們正好要記錄下來,作為有性能問題的依據。但是仍然可以繼續請求進行重試,說不定伺服器又能訪問了,這樣可以算出錯誤率

比如,登錄失敗了,那麼下單的操作由於登錄失敗,也會跟著失敗。

默認選擇此項,保證足夠的並發壓力

Start Next Thread Loop

如果出錯,則同一執行緒中的餘下請求將不再執行,直接重新開始新一輪迭代。

比如,登錄失敗了,那麼下單的操作將不再執行,重新開始。

如果想減少關聯請求報錯,可以選擇此項。

Stop Thread

一般不會設置此項,它指的是請求失敗後,停止當前執行緒,不再執行。這樣會導致運行執行緒越來越少,最後負載不夠,對伺服器的壓力不夠,測試結果不具參考性。

Stop Test

如果某一執行緒的某一請求失敗了,停止所有執行緒測試。

但是每個執行緒還是會執行完當前迭代後再停止。相當於 Continue 到當前迭代結束。

比如執行緒 1 正好執行到登錄,有其他執行緒出錯了,執行緒 1 也會執行完下單操作才會停止。

Stop Test Now

如果有執行緒的請求失敗了,立即停止所有執行緒,不再執行。

Thread Properties

Number of Threads (users)

運行的執行緒數設置,一個執行緒對應一個模擬用戶。

Ramp-up period (seconds)

所有執行緒在多長時間內開始運行,單位是秒。

比如我們設置執行緒數為 50,此處設置 10 秒,那麼每秒就會啟動 50 / 10,5 個執行緒。如果設置為 0 秒,則 50 個執行緒會立刻啟動。如果設置為 100 秒,就會每隔 100 / 50, 2 秒 啟動 1 個執行緒。

Ramp-up period的大小問題

Ramp-up period的大小問題,對於初學者來說是最容易困擾的。

以下是 5 個執行緒依次從啟動到執行退出的示意圖:

image-20201109162100237

紅色框起來的部分才是真正 5 個執行緒並發請求的時間段。

假設我們設置 20 個執行緒,只運行 1 次迭代,看看不同的啟動時間設置會有結果有何不同。

如果啟動時間設置為 0,那麼測試一開始就會產生 20 個並發請求,伺服器萬一只能承受 15 個並發,豈不是一上來就 gg 了,還測個什麼呀。

如果啟動時間設置為 40,那麼會每隔 2 秒 啟動 1 個執行緒。萬一執行緒執行不到 1 秒就退出了,第 2 個執行緒 啟動的時候,第 1 個執行緒已經退出了,不就是只產生了 1 個並發請求么。

那麼設置成多少合適呢?我也不知道,但是結合我查閱的資料,可以給出一個參考意見。

第一步,把執行緒組跑 1 次(可以在執行緒組元件上右鍵選擇 Validate),從聚合報告獲取到吞吐量(Throughput)。

第二步,用執行緒數量除以吞吐量,得出啟動時間。

例如,200 個執行緒,跑一次獲取到吞吐量為 4/sec,啟動時間為 200 / 4 = 50。這樣設置以後,第 2 個執行緒啟動後,剛好第 1 個執行緒執行完開始新的迭代,從而形成梯度遞增的並發請求。

Loop Count

迭代次數。可以填寫數字指定迭代次數。也可以勾選 Infinite,表示無限迭代,一直運行到測試停止或異常崩潰。

Same user on each iteration

在 JMeter 中,user 就是執行緒,此選項的意思是說每個迭代都用相同的執行緒。

這個得從老版本講起,在以前 3.x 和 4.x 版本的 JMeter 中,是沒有這個選項的。創建好 1 個執行緒後,每次迭代都是用這個執行緒,直到測試結束。它的影響就是,比如登錄,加了 HTTP Cookie 管理器以後,單個執行緒多次迭代(注意不是多個執行緒哦)登錄用的都是相同的 Cookie。

5.x 版本加入了這個選項,可以控制每次迭代是否創建新的執行緒。同時在 HTTP Cookie 管理器也增加了一個選項,控制是否清除舊 Cookie:

image-20201109103500031

默認這個 Same user on each iteration 的選項是勾選的。因為銷毀和創建執行緒本身就會佔用資源,可能會影響性能測試結果。

Delay Thread creation until needed

跟 JVM 創建執行緒時機有關,實際運用勾不勾選都不影響測試結果,保持默認就好。

Specify Thread lifetime

Duration

持續時間,單位秒。Loop Count 勾選了 Infinite,才有作用。

Startup delay

啟動延遲,單位秒。延遲到時間後再運行執行緒。

簡單回顧

本文首先解析了 JMeter 為什麼能做性能測試的原因,接著對執行緒組編輯區的選擇進行了講解,重點梳理了Ramp-up period的大小問題。此外,JMeter Plugins 還提供了兩個執行緒組元件 Ultimate Thread Group 與 Stepping Thread Group,以滿足浪涌(波濤狀,多個波峰)的場景。筆者水平有限,若有錯誤,請指正。

參考資料:1.《全棧性能測試修鍊寶典JMeter實戰》

2.//www.cnblogs.com/hjhsysu/p/9189897.html