深入淺出開源效能測試工具 Locust (使用篇 2)

debugtalk發表於2019-02-14

《深入淺出開源效能測試工具 Locust (使用篇 1)》

Locust執行模式

在開始執行Locust指令碼之前,我們先來看下Locust支援的執行模式。

執行Locust時,通常會使用到兩種執行模式:單程式執行和多程式分散式執行。

單程式執行模式的意思是,Locust所有的虛擬併發使用者均執行在單個Python程式中,具體從使用形式上,又分為no_webweb兩種形式。該種模式由於單程式的原因,並不能完全發揮壓力機所有處理器的能力,因此主要用於除錯指令碼和小併發壓測的情況。

當併發壓力要求較高時,就需要用到Locust的多程式分散式執行模式。從字面意思上看,大家可能第一反應就是多臺壓力機同時執行,每臺壓力機分擔負載一部分的壓力生成。的確,Locust支援任意多臺壓力機(一主多從)的分散式執行模式,但這裡說到的多程式分散式執行模式還有另外一種情況,就是在同一臺壓力機上開啟多個slave的情況。這是因為當前階段大多數計算機的CPU都是多處理器(multiple processor cores),單程式執行模式下只能用到一個處理器的能力,而通過在一臺壓力機上執行多個slave,就能呼叫多個處理器的能力了。比較好的做法是,如果一臺壓力機有N個處理器核心,那麼就在這臺壓力機上啟動一個masterNslave。當然,我們也可以啟動N的倍數個slave,但是根據我的試驗資料,效果跟N個差不多,因此只需要啟動Nslave即可。

指令碼除錯

Locust指令碼編寫完畢後,通常不會那麼順利,在正式開始效能測試之前還需要先除錯執行下。

不過,Locust指令碼雖然為Python指令碼,但卻很難直接當做Python指令碼執行起來,為什麼呢?這主要還是因為Locust指令碼中引用了HttpLocustTaskSet這兩個類,如果要想直接對其進行呼叫測試,會發現編寫啟動指令碼是一個比較困難的事情。因為這個原因,剛接觸Locust的同學可能就會覺得Locust指令碼不好除錯。

但這個問題也能克服,那就是藉助Locust的單程式no_web執行模式。

Locust的單程式no_web執行模式中,我們可以通過--no_web引數,指定併發數(-c)和總執行次數(-n),直接在Terminal中執行指令碼。

在此基礎上,當我們想要除錯Locust指令碼時,就可以在指令碼中需要除錯的地方通過print列印日誌,然後將併發數和總執行次數都指定為1,執行形式如下所示。

$ locust -f locustfile.py --no_web -c 1 -n 1複製程式碼

通過這種方式,我們就能很方便地對Locust指令碼進行除錯了。

執行測試

Locust指令碼除錯通過後,就算是完成了所有準備工作,可以開始進行壓力測試了。

Locust是通過在Terminal中執行命令進行啟動的,通用的引數有如下兩個:

  • -H, --host:被測系統的host,若在Terminal中不進行指定,就需要在Locust子類中通過host引數進行指定;
  • -f, --locustfile:指定執行的Locust指令碼檔案;

除了這兩個通用的引數,我們還需要根據實際測試場景,選擇不同的Locust執行模式,而模式的指定也是通過其它引數來進行控制的。

單程式執行

no_web

如果採用no_web形式,則需使用--no-web引數,並會用到如下幾個引數。

  • -c, --clients:指定併發使用者數;
  • -n, --num-request:指定總執行測試;
  • -r, --hatch-rate:指定併發加壓速率,預設值位1。
$ locust -H http://debugtalk.com -f demo.py --no-web -c1 -n2
[2017-02-21 21:27:26,522] Leos-MacBook-Air.local/INFO/locust.main: Starting Locust 0.8a2
[2017-02-21 21:27:26,523] Leos-MacBook-Air.local/INFO/locust.runners: Hatching and swarming 1 clients at the rate 1 clients/s...
 Name                                                          # reqs      # fails     Avg     Min     Max  |  Median   req/s
--------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------
 Total                                                              0     0(0.00%)                                       0.00

[2017-02-21 21:27:27,526] Leos-MacBook-Air.local/INFO/locust.runners: All locusts hatched: WebsiteUser: 1
[2017-02-21 21:27:27,527] Leos-MacBook-Air.local/INFO/locust.runners: Resetting stats

 Name                                                          # reqs      # fails     Avg     Min     Max  |  Median   req/s
--------------------------------------------------------------------------------------------------------------------------------------
 GET /about/                                                        0     0(0.00%)       0       0       0  |       0    0.00
--------------------------------------------------------------------------------------------------------------------------------------
 Total                                                              0     0(0.00%)                                       0.00

 Name                                                          # reqs      # fails     Avg     Min     Max  |  Median   req/s
--------------------------------------------------------------------------------------------------------------------------------------
 GET /about/                                                        1     0(0.00%)      17      17      17  |      17    0.00
--------------------------------------------------------------------------------------------------------------------------------------
 Total                                                              1     0(0.00%)                                       0.00

[2017-02-21 21:27:32,420] Leos-MacBook-Air.local/INFO/locust.runners: All locusts dead

[2017-02-21 21:27:32,421] Leos-MacBook-Air.local/INFO/locust.main: Shutting down (exit code 0), bye.
 Name                                                          # reqs      # fails     Avg     Min     Max  |  Median   req/s
--------------------------------------------------------------------------------------------------------------------------------------
 GET /                                                              1     0(0.00%)      20      20      20  |      20    0.00
 GET /about/                                                        1     0(0.00%)      17      17      17  |      17    0.00
--------------------------------------------------------------------------------------------------------------------------------------
 Total                                                              2     0(0.00%)                                       0.00

Percentage of the requests completed within given times
 Name                                                           # reqs    50%    66%    75%    80%    90%    95%    98%    99%   100%
--------------------------------------------------------------------------------------------------------------------------------------
 GET /                                                               1     20     20     20     20     20     20     20     20     20
 GET /about/                                                         1     17     17     17     17     17     17     17     17     17
--------------------------------------------------------------------------------------------------------------------------------------複製程式碼

web

如果採用web形式,,則通常情況下無需指定其它額外引數,Locust預設採用8089埠啟動web;如果要使用其它埠,就可以使用如下引數進行指定。

  • -P, --port:指定web埠,預設為8089.
$ locust -H http://debugtalk.com -f demo.py
[2017-02-21 21:31:26,334] Leos-MacBook-Air.local/INFO/locust.main: Starting web monitor at *:8089
[2017-02-21 21:31:26,334] Leos-MacBook-Air.local/INFO/locust.main: Starting Locust 0.8a2複製程式碼

此時,Locust並沒有開始執行測試,還需要在Web頁面中配置引數後進行啟動。

如果Locust執行在本機,在瀏覽器中訪問http://localhost:8089即可進入Locust的Web管理頁面;如果Locust執行在其它機器上,那麼在瀏覽器中訪問http://locust_machine_ip:8089即可。

Locust的Web管理頁面中,需要配置的引數只有兩個:

  • Number of users to simulate: 設定併發使用者數,對應中no_web模式的-c, --clients引數;
  • Hatch rate (users spawned/second): 啟動虛擬使用者的速率,對應著no_web模式的-r, --hatch-rate引數。

引數配置完畢後,點選【Start swarming】即可開始測試。

多程式分散式執行

不管是單機多程式,還是多機負載模式,執行方式都是一樣的,都是先執行一個master,再啟動多個slave

啟動master時,需要使用--master引數;同樣的,如果要使用8089以外的埠,還需要使用-P, --port引數。

$ locust -H http://debugtalk.com -f demo.py --master --port=8088
[2017-02-21 22:59:57,308] Leos-MacBook-Air.local/INFO/locust.main: Starting web monitor at *:8088
[2017-02-21 22:59:57,310] Leos-MacBook-Air.local/INFO/locust.main: Starting Locust 0.8a2複製程式碼

master啟動後,還需要啟動slave才能執行測試任務。

啟動slave時需要使用--slave引數;在slave中,就不需要再指定埠了。

$ locust -H http://debugtalk.com -f demo.py --slave
[2017-02-21 23:07:58,696] Leos-MacBook-Air.local/INFO/locust.main: Starting Locust 0.8a2
[2017-02-21 23:07:58,696] Leos-MacBook-Air.local/INFO/locust.runners: Client 'Leos-MacBook-Air.local_980ab0eec2bca517d03feb60c31d6a3a' reported as
 ready. Currently 2 clients ready to swarm.複製程式碼

如果slavemaster不在同一臺機器上,還需要通過--master-host引數再指定master的IP地址。

$ locust -H http://debugtalk.com -f demo.py --slave --master-host=<locust_machine_ip>
[2017-02-21 23:07:58,696] Leos-MacBook-Air.local/INFO/locust.main: Starting Locust 0.8a2
[2017-02-21 23:07:58,696] Leos-MacBook-Air.local/INFO/locust.runners: Client 'Leos-MacBook-Air.local_980ab0eec2bca517d03feb60c31d6a3a' reported as
 ready. Currently 2 clients ready to swarm.複製程式碼

masterslave都啟動完畢後,就可以在瀏覽器中通過http://locust_machine_ip:8089進入Locust的Web管理頁面了。使用方式跟單程式web形式完全相同,只是此時是通過多程式負載來生成併發壓力,在web管理介面中也能看到實際的slave數量。

測試結果展示

Locust在執行測試的過程中,我們可以在web介面中實時地看到結果執行情況。

相比於LoadRunnerLocust的結果展示十分簡單,主要就四個指標:併發數RPS響應時間異常率。但對於大多數場景來說,這幾個指標已經足夠了。

深入淺出開源效能測試工具 Locust (使用篇 2)

在上圖中,RPS平均響應時間這兩個指標顯示的值都是根據最近2秒請求響應資料計算得到的統計值,我們也可以理解為瞬時值。

如果想看效能指標資料的走勢,就可以在Charts欄檢視。在這裡,可以檢視到RPS平均響應時間在整個執行過程中的波動情況。這個功能之前在Locust中一直是缺失的,直到最近,這個坑才被我之前在阿里移動的同事(網路IDmyzhan)給填上了。當前該功能已經合併到Locust了,更新到最新版即可使用。

深入淺出開源效能測試工具 Locust (使用篇 2)

除了以上資料,Locust還提供了整個執行過程資料的百分比統計值,例如我們常用的90%響應時間響應時間中位值,該資料可以通過Download response time distribution CSV獲得,資料展示效果如下所示。

深入淺出開源效能測試工具 Locust (使用篇 2)

總結

通過前面對Locust全方位的講解,相信大家對Locust的功能特性已經非常熟悉了,在實際專案中將Locust作為生產力工具應該也沒啥問題了。

不過,任何一款工具都不是完美的,必定都會存在一些不足之處。但是好在Locust具有極強的可定製型,當我們遇到一些特有的需求時,可以在Locust上很方便地實現擴充套件。

還是前面提到的那位技術大牛(myzhan),他為了擺脫CPythonGILgeventmonkey_patch(),將Locustslave端採用golang進行了重寫,採用goroutine取代了gevent。經過測試,相較於原生的Python實現,他的這套golang實現具有5~10倍以上的效能提升。當前,他已經將該實現開源,專案名稱為myzhan/boomer,如果大家感興趣,可以閱讀他的部落格文章進一步瞭解,《用 golang 來編寫壓測工具》

如果我們也想在Locust的基礎上進行二次開發,那要怎麼開始呢?

毫無疑問,閱讀Locust的專案原始碼是必不可少的第一步。可能對於很多人來說,閱讀開源專案原始碼是一件十分困難的事情,不知道如何著手,在知乎上也看到好多關於如何閱讀開源專案原始碼的提問。事實上,Locust專案的程式碼結構清晰,核心程式碼量也比較少,十分適合閱讀學習。哪怕只是想體驗下閱讀開源專案原始碼,或者說想提升下自己的Python技能,Locust也是個不錯的選擇。

在下一篇文章中,我將對Locust原始碼進行解析,《深入淺出開源效能測試工具Locust(原始碼篇)》,敬請期待!

GitHub專案地址

Stormer

硬廣

歡迎關注我的個人部落格和微信公眾號。

相關文章