Locust性能測(cè)試工具核心技術(shù)@task和@events
本文轉(zhuǎn)載自微信公眾號(hào)「dongfanger」,作者dongfanger。轉(zhuǎn)載本文請(qǐng)聯(lián)系dongfanger公眾號(hào)。
Tasks和Events是Locust性能測(cè)試工具的核心技術(shù),有了它們,Locust才能稱得上是一個(gè)性能工具。
Tasks
從上篇文章知道,locustfile里面必須要有一個(gè)類,繼承User類,當(dāng)性能測(cè)試開始后,會(huì)產(chǎn)生一個(gè)User類實(shí)例,這就是常說(shuō)的模擬用戶。這些用戶會(huì)選擇task執(zhí)行,休眠一會(huì),再選擇新的task,不斷迭代。
task是Python中的可調(diào)用對(duì)象,它是一項(xiàng)任務(wù),對(duì)于Web系統(tǒng)來(lái)說(shuō),可以是登錄、查詢、下訂單、支付等等。
@task裝飾器
@task是定義task最簡(jiǎn)單直接的方式,比如:
- from locust import User, task, constant
- class MyUser(User):
- wait_time = constant(1)
- @task
- def my_task(self):
- print("User instance (%r) executing my_task" % self)
@task有一個(gè)可選參數(shù),用來(lái)設(shè)置task的選擇權(quán)重,比如:
- from locust import User, task, between
- class MyUser(User):
- wait_time = between(5, 15)
- @task(3)
- def task1(self):
- pass
- @task(6)
- def task2(self):
- pass
task2比task1被選擇的可能性大兩倍。
tasks屬性
除了@task裝飾器,還可以設(shè)置User類的tasks屬性來(lái)定義任務(wù),比如:
- from locust import User, constant
- def my_task(user):
- pass
- class MyUser(User):
- tasks = [my_task]
- wait_time = constant(1)
注意,my_task()函數(shù)有一個(gè)參數(shù),它是User類的實(shí)例。
tasks可以是一個(gè)列表:
- tasks = [my_task1, my_task2, my_task3]
Locust會(huì)使用Python中的random.choice()從里面隨機(jī)選取。
tasks也可以是一個(gè)字典:
- {my_task: 3, another_task: 1}
后面的int型鍵值代表的是被選擇權(quán)重,這個(gè)字典等價(jià)于列表:
- [my_task, my_task, my_task, another_task]
@tag裝飾器
@tag用來(lái)打標(biāo)記,在運(yùn)行時(shí)選擇哪些task執(zhí)行,哪些task不執(zhí)行。比如:
- class MyUser(User):
- wait_time = constant(1)
- @tag('tag1')
- @task
- def task1(self):
- pass
- @tag('tag1', 'tag2')
- @task
- def task2(self):
- pass
- @tag('tag3')
- @task
- def task3(self):
- pass
- @task
- def task4(self):
- pass
- 如果使用--tags tag1,那么只有task1和task2會(huì)被選擇。
- 如果使用--tags tag2 tag3,那么只有task2和task3會(huì)被選擇。
- 如果使用--exclude-tags tag3,那么只有task1、task2和task4會(huì)被選擇。
注意,exclude的優(yōu)先級(jí)更高,如果某個(gè)tag既包括又排除,那么會(huì)被排除。
Events
@task定義了性能測(cè)試的執(zhí)行動(dòng)作,@events作為補(bǔ)充,定義了測(cè)試開始前和測(cè)試結(jié)束后的處理。
注意,每個(gè)模擬用戶開始和結(jié)束的處理是使用的User類的on_start()和on_stop()方法。
test_start和test_stop
測(cè)試開始前和測(cè)試結(jié)束后觸發(fā)。示例:
- from locust import events
- @events.test_start.add_listener
- def on_test_start(environment, **kwargs):
- print("A new test is starting")
- @events.test_stop.add_listener
- def on_test_stop(environment, **kwargs):
- print("A new test is ending")
分布式執(zhí)行時(shí),它們只會(huì)在master節(jié)點(diǎn)生效。
init
init和test_start不同,它會(huì)在每個(gè)Locust進(jìn)程開始時(shí)觸發(fā),分布式執(zhí)行時(shí),每個(gè)節(jié)點(diǎn)(worker進(jìn)程)都會(huì)生效。
- from locust import events
- from locust.runners import MasterRunner
- @events.init.add_listener
- def on_locust_init(environment, **kwargs):
- if isinstance(environment.runner, MasterRunner):
- print("I'm on master node")
- else:
- print("I'm on a worker or standalone node")
Events是一項(xiàng)hook技術(shù),在學(xué)習(xí)Locust高級(jí)用法時(shí)再做進(jìn)一步介紹。
Locust項(xiàng)目結(jié)構(gòu)
官方建議如下:
common/
__init__.py
auth.py
config.py
locustfile.py或者locustfiles/
api.py
website.py
requirements.txt
FastHttpUser
從上篇文章可以知道,HttpUser類比User類更常用,它的client屬性是HttpSession類(requests.Session子類)的一個(gè)實(shí)例,可以使用requests發(fā)HTTP請(qǐng)求:
- # 使用HttpUser
- from locust import HttpUser,task,constant
- class MyUser(User):
- wait_time = constant(1)
- @task
- def my_task1(self):
- with self.client.get("https://www.baidu.com/", catch_response=True) as res:
- if res.status_code == 200:
- print("成功")
- else:
- print("失敗")
但是requests性能是不太好的,如果要產(chǎn)生更高的壓力,建議使用FastHttpUser,性能可以提升5到6倍:
- # 使用FastHttpUser
- from locust import task, constant
- from locust.contrib.fasthttp import FastHttpUser
- class MyUser(FastHttpUser):
- wait_time = constant(1)
- @task
- def my_task(self):
- with self.client.get("https://www.baidu.com/", catch_response=True) as response:
- if response.status_code == 200:
- print("成功")
- else:
- print("失敗")
由于它們的API不一樣,都有各自的適用場(chǎng)景,所以FastHttpUser不能完全替代HttpUser。
小結(jié)
本文嚴(yán)格來(lái)說(shuō)是上篇文章《locustfile中的User類和HttpUser類》的下篇,介紹了核心技術(shù)Tasks和Events,并給出了官方推薦的項(xiàng)目結(jié)構(gòu),最后介紹了比HttpUser性能更好的FastHttpUser,如果想要更多的并發(fā),可以考慮使用后者。經(jīng)過(guò)這兩篇文章的學(xué)習(xí),已經(jīng)可以開始動(dòng)手實(shí)踐使用Locust進(jìn)行性能測(cè)試了。如果使用locust命令啟動(dòng)后,無(wú)法打開網(wǎng)頁(yè),可以試試加上參數(shù):locust --web-host="127.0.0.1"。
參考資料:
https://zhuanlan.zhihu.com/p/118470760
https://docs.locust.io/en/stable/writing-a-locustfile.html#tasks
https://www.axihe.com/tools/locust/increase-performance.html
https://blog.csdn.net/u012002125/article/details/113363768