續《深入淺出開源效能測試工具 Locust (使用篇 1)》
Locust執行模式
在開始執行Locust
指令碼之前,我們先來看下Locust
支援的執行模式。
執行Locust
時,通常會使用到兩種執行模式:單程式執行和多程式分散式執行。
單程式執行模式的意思是,Locust
所有的虛擬併發使用者均執行在單個Python
程式中,具體從使用形式上,又分為no_web
和web
兩種形式。該種模式由於單程式的原因,並不能完全發揮壓力機所有處理器的能力,因此主要用於除錯指令碼和小併發壓測的情況。
當併發壓力要求較高時,就需要用到Locust
的多程式分散式執行模式。從字面意思上看,大家可能第一反應就是多臺壓力機同時執行,每臺壓力機分擔負載一部分的壓力生成。的確,Locust
支援任意多臺壓力機(一主多從)的分散式執行模式,但這裡說到的多程式分散式執行模式還有另外一種情況,就是在同一臺壓力機上開啟多個slave
的情況。這是因為當前階段大多數計算機的CPU都是多處理器(multiple processor cores
),單程式執行模式下只能用到一個處理器的能力,而通過在一臺壓力機上執行多個slave
,就能呼叫多個處理器的能力了。比較好的做法是,如果一臺壓力機有N
個處理器核心,那麼就在這臺壓力機上啟動一個master
,N
個slave
。當然,我們也可以啟動N
的倍數個slave
,但是根據我的試驗資料,效果跟N
個差不多,因此只需要啟動N
個slave
即可。
指令碼除錯
Locust
指令碼編寫完畢後,通常不會那麼順利,在正式開始效能測試之前還需要先除錯執行下。
不過,Locust
指令碼雖然為Python指令碼,但卻很難直接當做Python指令碼執行起來,為什麼呢?這主要還是因為Locust
指令碼中引用了HttpLocust
和TaskSet
這兩個類,如果要想直接對其進行呼叫測試,會發現編寫啟動指令碼是一個比較困難的事情。因為這個原因,剛接觸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.複製程式碼
如果slave
與master
不在同一臺機器上,還需要通過--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.複製程式碼
master
和slave
都啟動完畢後,就可以在瀏覽器中通過http://locust_machine_ip:8089
進入Locust
的Web管理頁面了。使用方式跟單程式web
形式完全相同,只是此時是通過多程式負載來生成併發壓力,在web
管理介面中也能看到實際的slave
數量。
測試結果展示
Locust
在執行測試的過程中,我們可以在web
介面中實時地看到結果執行情況。
相比於LoadRunner
,Locust
的結果展示十分簡單,主要就四個指標:併發數
、RPS
、響應時間
、異常率
。但對於大多數場景來說,這幾個指標已經足夠了。
在上圖中,RPS
和平均響應時間
這兩個指標顯示的值都是根據最近2秒請求響應資料計算得到的統計值,我們也可以理解為瞬時值。
如果想看效能指標資料的走勢,就可以在Charts
欄檢視。在這裡,可以檢視到RPS
和平均響應時間
在整個執行過程中的波動情況。這個功能之前在Locust
中一直是缺失的,直到最近,這個坑才被我之前在阿里移動
的同事(網路IDmyzhan
)給填上了。當前該功能已經合併到Locust
了,更新到最新版即可使用。
除了以上資料,Locust
還提供了整個執行過程資料的百分比統計值,例如我們常用的90%響應時間
、響應時間中位值
,該資料可以通過Download response time distribution CSV
獲得,資料展示效果如下所示。
總結
通過前面對Locust
全方位的講解,相信大家對Locust
的功能特性已經非常熟悉了,在實際專案中將Locust
作為生產力工具應該也沒啥問題了。
不過,任何一款工具都不是完美的,必定都會存在一些不足之處。但是好在Locust
具有極強的可定製型,當我們遇到一些特有的需求時,可以在Locust
上很方便地實現擴充套件。
還是前面提到的那位技術大牛(myzhan
),他為了擺脫CPython
的GIL
和gevent
的 monkey_patch()
,將Locust
的slave
端採用golang
進行了重寫,採用goroutine
取代了gevent
。經過測試,相較於原生的Python
實現,他的這套golang
實現具有5~10
倍以上的效能提升。當前,他已經將該實現開源,專案名稱為myzhan/boomer
,如果大家感興趣,可以閱讀他的部落格文章進一步瞭解,《用 golang 來編寫壓測工具》。
如果我們也想在Locust
的基礎上進行二次開發,那要怎麼開始呢?
毫無疑問,閱讀Locust
的專案原始碼是必不可少的第一步。可能對於很多人來說,閱讀開源專案原始碼是一件十分困難的事情,不知道如何著手,在知乎上也看到好多關於如何閱讀開源專案原始碼的提問。事實上,Locust
專案的程式碼結構清晰,核心程式碼量也比較少,十分適合閱讀學習。哪怕只是想體驗下閱讀開源專案原始碼,或者說想提升下自己的Python
技能,Locust
也是個不錯的選擇。
在下一篇文章中,我將對Locust
原始碼進行解析,《深入淺出開源效能測試工具Locust(原始碼篇)》,敬請期待!
GitHub專案地址
硬廣
歡迎關注我的個人部落格和微信公眾號。
- 個人部落格: debugtalk.com
- 微信公眾號:
DebugTalk