Locust性能測試實施細節(jié)

引言

當我們做Web系統(tǒng)性能測試方案時,壓力模擬工具的選擇通常是一個繞不開的環(huán)節(jié)。對于大部分互聯(lián)網(wǎng)公司的業(yè)務規(guī)模和測試資源投入,JMeter這個老牌開源性能測試工具能夠滿足大部分測試需求,它也可能是世面上書籍、博客教程豐富程度僅次于LoadRunner的性能測試工具。然而當我們的場景需要模擬的并發(fā)用戶數(shù)以千為單位時,使用JMeter的成本越來越大,甚至超出我們掌握的資源。此時,我們開始尋找更低成本的方案,而Locust,為這樣的方案帶來了一種可能。

簡介

Locust是開源、使用Python開發(fā)、基于事件、支持分布式并且提供Web UI進行測試執(zhí)行和結(jié)果展示的性能測試工具。而它之所以能夠在資源占用方面明顯優(yōu)于JMeter,一個關(guān)鍵點在于兩者模擬虛擬用戶的方式不同,JMeter通過線程來作為虛擬用戶,而Locust借助gevent庫對協(xié)程的支持,以greenlet來實現(xiàn)對用戶的模擬,相同配置下Locust能支持的并發(fā)用戶數(shù)相比JMeter可以達到一個數(shù)量級的提升。
Locust使用Python代碼定義測試場景,目前支持Python 2.7, 3.3, 3.4, 3.5, 和3.6。它自帶一個Web UI,用于定義用戶模型,發(fā)起測試,實時測試數(shù)據(jù),錯誤統(tǒng)計等,在最新未正式發(fā)布的v0.8a2(當前最新發(fā)布版本v0.8a1),還提供QPS、評價響應時間等幾個簡單的圖表。

Summary Report
Charts

本文不會介紹Locust最基礎的部署、運行等Quick start式內(nèi)容,這部分內(nèi)容請直接參照官網(wǎng)Quick start或者搜索Locust入門的博客,本文主要介紹一些目前網(wǎng)絡上還比較缺少的,真正要用Locust來做Web系統(tǒng)性能測試時通常需要用到的內(nèi)容或者可能遇到的問題

v0.8a2<a id="a2"></a>

如前文所說,當前官方最新發(fā)布的版本為v0.8a1,還不包含圖表特性,而在官方Github上已經(jīng)在v0.8a2完成了圖表特性的合并,想要提前體驗可以直接從Github獲取master分支的代碼,覆蓋`[PythonHome]\Lib\site-packages`中的locust目錄即可。

指定Web host

在Linux系統(tǒng)多網(wǎng)卡情況下,Locust自動選擇網(wǎng)卡時可能會遇到error: [Errno 97] Address family not supported by protocol錯誤,此時可以通過直接指定web host來解決問題,使用選項--web-host來指定可用的地址,例:

locust -f xxx.py --web-host=127.0.0.1
locust -f xxx.py --web-host=192.168.1.2
locust -f xxx.py --web-host=localhost

斷言

當我們沒有自定義斷言時,測試請求結(jié)果的狀態(tài)(success/fail)取決于Http請求是否有異常出現(xiàn),而在對我們的Web系統(tǒng)實施性能測試時,當我們需要更準確的業(yè)務成功率數(shù)據(jù)時,就需要通過對響應狀態(tài)碼、Response body等數(shù)據(jù)進行校驗來給出結(jié)果,此時,可以通過ResponseContextManager來實現(xiàn)。首先在場景代碼的發(fā)起請求參數(shù)中通過catch_response=True來捕獲響應數(shù)據(jù),然后對響應數(shù)據(jù)進行校驗,最后使用success()/failure()兩個方法來標識請求結(jié)果的狀態(tài)。例:

from locust import HttpLocust, TaskSet,task
class UserBehavior(TaskSet):
    @task(2)
    def foo(self):
        with self.client.get("/", catch_response=True) as response:
            if response.status_code == 200:
                response.success()
        @task(1)
         def bar(self):
                reqBody = '{"username":"ellen_key", "password":"education"}'
                with self.client.post("/login", reqBody, catch_response=True) as response: 
                        if response.content == "":
                                response.failure("No data")
class WebsiteUser(HttpLocust):
    task_set = UserBehavior
    host = "http://foo.bar.com"
    min_wait = 0
    max_wait = 0

Json解析

Json作為一種輕量級的數(shù)據(jù)交換格式,以及被如今的互聯(lián)網(wǎng)系統(tǒng)廣泛采用。上一節(jié)的示例中,我們使用content獲取完整的響應內(nèi)容,實際測試實施中,對于動態(tài)的響應結(jié)果,可能更多的采用校驗關(guān)鍵字段的方式對于Json格式的響應數(shù)據(jù),要獲取特定字段的值,可以直接使用內(nèi)置的Json解析實現(xiàn),例:
對于如下的響應結(jié)果:

{
  'code':0,
  'data':[
        {
          'id':123
        }
  ]
}

可以通過如下方式獲取其中的關(guān)鍵數(shù)據(jù):

with self.client.post("/login", reqBody, catch_response=True) as response: 
    json_resp = response.json()
    code = json_resp["code"]
    data_len = len(json_resp["data"])
    id = json_resp["data"][0]["id"]

自定義標簽

從簡介的Summary report圖中可以看到,Locust的結(jié)果展示中,請求的默認名稱是url的path部分,而為了報告更直觀,或者當同一個業(yè)務有動態(tài)的path(如/user/[userid]),需要聚合時,可以通過name參數(shù)來自定義標簽實現(xiàn),例:

with  self.client.get("/account/{accountID}", catch_response=True, name = "getAccount") as resp:

分布式運行

Locust的分布式運行,master和slave節(jié)點都需要有場景腳本,分別以如下命令啟動:

  • master:locust -f locustfile.py --master --web-host=x.x.x.x
  • slave:locust -f locustfile.py --slave --master-host=x.x.x.x
    master節(jié)點將運行Locust的Web UI服務,不會承擔任何施壓任務(不會模擬虛擬用戶)。
    如前面的簡介,Locust模擬并發(fā)用戶是使用協(xié)程,也因此對于多核CPU的服務器,為良好的利用多核能力,建議一臺slave服務器運行與CPU核數(shù)相當?shù)膕lave。

總結(jié)

Locust作為一個年輕的、輕量級的性能測試工具,網(wǎng)絡上相關(guān)的應用文獻特別是中文文獻相對較少,而且多數(shù)是Quick start式的指引,對于一些實施的細節(jié)信息還比較欠缺,本文根據(jù)作者的實際應用經(jīng)驗,列舉了部分使用細節(jié),希望能為需要的朋友提供一點有用的信息。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容