版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。歡迎通路我的部落格 https://blog.csdn.net/smooth00/article/details/80014622
我是一個用慣Loadrunner的人,由于Loadrunner過于重量級,不友善在雲端部署和使用,是以平常在這方面隻能選擇Jmeter,Jmeter的開源性和輕量化是我最喜歡的地方,但是Jmeter的腳本開發模式是我最不喜歡的地方:jmx腳本對應的XML格式太不直覺,不友善維護和管理,代碼調試也不友善(對于我們這些不願意依賴于腳本錄制的人來說,這點很重要),另外不喜歡的就是Jmeter的性能和穩定性,即使用了Non-GUI + 分布式壓測的模式,Master節點的承受能力也不如Loadrunner。
是以我真的比較傾向于找一款既能像Loadrunner那樣高性能高穩定性,代碼維護管理自如,又能像Jmeter那樣輕量級的、高擴充性的測試工具。目前來看好像不存在這種工具,但是有一款性能測試工具叫Gatling,與Jmeter進行分析比較了一下,覺得它很有潛力,興許哪一天,它借鑒了Jmeter的一些優點,就達到了我的要求,或者Jmeter借鑒一下它,做個翻天腹地的改造,那也未嘗不可。
對于Gatling的優點網上也總結了很多,我也不多說,但是光從測試場景配置上來說,Gatling就不輸Loadrunner,拿例子來說明:
setUp(
scn.inject(
nothingFor(4 seconds), // 場景1
atOnceUsers(10), // 場景2
rampUsers(10) over(5 seconds), // 場景3
constantUsersPerSec(20) during(15 seconds), // 場景4
constantUsersPerSec(20) during(15 seconds) randomized, // 場景5
rampUsersPerSec(10) to(20) during(10 minutes), // 場景6
rampUsersPerSec(10) to(20) during(10 minutes) randomized, // 場景7
splitUsers(100) into(rampUsers(10) over(10 seconds)) separatedBy(10 seconds), // 場景8
splitUsers(100) into(rampUsers(10) over(10 seconds)) separatedBy(atOnceUsers(30)), // 場景9
heavisideUsers(100) over(20 seconds) // 場景10
).protocols(httpConf)
)
以上代碼包含了10個場景的例子:
1. nothingFor(4 seconds)
在指定的時間段(4 seconds)内什麼都不幹
2. atOnceUsers(10)
一次模拟的使用者數量(10)。
3. rampUsers(10) over(5 seconds)
在指定的時間段(5 seconds)内逐漸增加使用者數到指定的數量(10)。
4. constantUsersPerSec(10) during(20 seconds)
以固定的速度模拟使用者,指定每秒模拟的使用者數(10),指定模拟測試時間長度(20 seconds)。
5. constantUsersPerSec(10) during(20 seconds) randomized
以固定的速度模拟使用者,指定每秒模拟的使用者數(10),指定模拟時間段(20 seconds)。使用者數将在随機被随機模拟(毫秒級别)。
6. rampUsersPerSec(10) to (20) during(20 seconds)
在指定的時間(20 seconds)内,使每秒模拟的使用者從數量1(10)逐漸增加到數量2(20),速度勻速。
7. rampUsersPerSec(10) to (20) during(20 seconds) randomized
在指定的時間(20 seconds)内,使每秒模拟的使用者從數量1(10)增加到數量2(20),速度随機。
8. splitUsers(100) into(rampUsers(10) over(10 seconds)) separatedBy(10 seconds)
反複執行所定義的模拟步驟(rampUsers(10) over(10 seconds)),每次暫停指定的時間(10 seconds),直到總數達到指定的數量(100)
9. splitUsers(100) into(rampUsers(10) over(10 seconds)) separatedBy(atOnceUsers(30))
反複依次執行所定義的模拟步驟1(rampUsers(10) over(10 seconds))和模拟步驟2(atOnceUsers(30)),直到總數達到指定的數量(100)左右
10. heavisideUsers(100) over(10 seconds)
在指定的時間(10 seconds)内使用類似機關階躍函數的方法逐漸增加模拟并發的使用者,直到總數達到指定的數量(100).簡單說就是每秒并發使用者數遞增。
就拿場景8來說,可以制造一種波浪型壓力,非常适合模拟一種脈沖式的壓力測試或是某類穩定性測試(壓力按波峰波谷有規律的分布),如下所示:
------------------------------------------------------------------------------------------------------------------
雖然Gatling很讓我們驚奇,但就目前來說,還遠沒有達到我們的最佳選擇,不過研究它已經非常有必要了,畢竟一個好工具的普及不是一天兩天的事。Jmeter有那麼多不如意的地方,但我們還得繼續用呀,現在腳本的易維護性方面還不是最重要的問題,最緊迫的是如何對Jmeter進行減負,以實作穩定超高并發測試,目前隻能考慮以下的方式進行:
減負一,優化監聽(GUI模式,盡量不考慮)
1.“檢視結果樹”,需要勾選“僅日志錯誤”,這樣隻會儲存錯誤日志到記憶體,資料不會多。如果儲存所有,那麼會儲存每個請求資訊和相關資訊,而且這些資料都是儲存到jvm記憶體的,且常駐資料無法回收,上萬十萬大量請求很快就會壓垮jmeter。
2.“聚合報告”中小并(100以内)發可以保留;高并發去掉,添加“Simple Data Writer”且儲存csv格式資料。“聚合報告”是非常消耗cpu的。
3.其他監聽元件可以都去掉,測試完後通過儲存的結果,線下生成圖表報告
減負二,優化監聽(Non-GUI指令行模式)
1.“檢視結果樹”,需要勾選“僅日志錯誤”,需要設定路徑,儲存錯誤資訊到檔案,并且儲存所有資訊(點選Configure,勾選所有非CSV選項)
2.“聚合報告”指令行下無效
3. 其他監聽元件可以都去掉,基本在Non-GUI下無效
減負三,結果檔案優化
1. 結果資料一定要儲存為CSV格式(比起xml格式,每條資料會少很多)(可以用Non-GUI指令指定csv日志儲存)
2.“檢視結果樹”儲存的錯誤資訊要儲存為xml,可以儲存完整結果資訊,友善錯誤分析
減負四,如果要超高并發建議不要直接使用分布式壓測
1. jmeter分布部署隻是緩解問題,沒根本解決問題,高并發時master機器承受的壓力很大,形成單點,無法在高并發時提供穩定負載
2. 資料會寫可能丢失
3. 解決方法:需要手工運作slave,或利用jenkins同時觸發多台slave
減負五,再強調一下,建議用Non-GUI指令行模式運作,并且選擇Linux環境運作Jmeter也是很有必要的
1. 用Non-GUI運作jmeter生成csv報告,但别輸出html報告(需要高jvm記憶體來完成,是以分成兩步進行)
2. 修改jmeter的jvm記憶體(建議實體記憶體的一半,HEAP的xms和xmx,1G的csv報告建議對應2G的xmx大小),用高jvm記憶體來轉換csv報告至html報告(記憶體不夠就換機器來轉換報告)
減負六,可以選擇用Jmeter + Grafana + InfluxDB的方式,來代替報告檔案的生成,參考我的另一篇文章《
關于Jmeter長時間壓測的可視化監控報告》
1. 将Jmeter分布式叢集去中心化,Master節點不再負責收集和處理測試資料,隻負責排程slave節點
2. 支援多Master-slave,形成多路Jmeter測試叢集(利用Jenkins或其他排程工具同時觸發排程測試)