一棚瘟、簡(jiǎn)介
1.定義
- Locust是一款易于使用的分布式負(fù)載測(cè)試工具箭阶,完全基于事件,即一個(gè)locust節(jié)點(diǎn)也可以在一個(gè)進(jìn)程中支持?jǐn)?shù)千并發(fā)用戶捅暴,不使用回調(diào),使用輕量級(jí)過(guò)程(即在自己的進(jìn)程內(nèi)運(yùn)行)咧纠。
2.特點(diǎn)
- ①蓬痒、不需要編寫笨重的UI或者臃腫的XML代碼,基于協(xié)程而不是回調(diào)漆羔,腳本編寫簡(jiǎn)單易讀梧奢;
- ②、有一個(gè)基于we簡(jiǎn)潔的HTML+JS的UI用戶界面演痒,可以實(shí)時(shí)顯示相關(guān)的測(cè)試結(jié)果亲轨;
- ③、支持分布式測(cè)試嫡霞,用戶界面基于網(wǎng)絡(luò)瓶埋,因此具有跨平臺(tái)且易于擴(kuò)展的特點(diǎn);
- ④诊沪、所有繁瑣的I / O和協(xié)同程序都被委托給gevent养筒,替代其他工具的局限性;
3.比較
工具 | 區(qū)別 |
---|---|
jmeter | 需要在UI界面上通過(guò)選擇組件來(lái)“編寫”腳本端姚,模擬的負(fù)載是線程綁定的晕粪,意味著模擬的每個(gè)用戶,都需要一個(gè)單獨(dú)的線程渐裸。單臺(tái)負(fù)載機(jī)可模擬的負(fù)載數(shù)有限 |
locust | 通過(guò)編寫簡(jiǎn)單易讀的代碼完成測(cè)試腳本巫湘,基于事件装悲,同樣配置下,單臺(tái)負(fù)載機(jī)可模擬的負(fù)載數(shù)遠(yuǎn)超jmeter |
ps:但locust的局限性在于尚氛,目前其本身對(duì)測(cè)試過(guò)程的監(jiān)控和測(cè)試結(jié)果展示诀诊,不如jmeter全面和詳細(xì),需要進(jìn)行二次開發(fā)才能滿足需求越來(lái)越復(fù)雜的性能測(cè)試需要
二阅嘶、安裝
- 1.網(wǎng)上都有支持python的版本:2.7属瓣、3.4、3.5讯柔、3.6抡蛙、3.7(ps:本機(jī)為3.7)
- 2.windows/linux/系統(tǒng)安裝(ps:本機(jī)為windows10)
- ①、安裝命令
>通過(guò)pip安裝 >pip install locust
- ②魂迄、通過(guò)為pyzmq粗截、gevent和greenlet安裝預(yù)先構(gòu)建的二進(jìn)制包,然后在這里找到非官方的預(yù)制包捣炬,下載.whl文件后熊昌,使用 pip install name-of-file.whl 命令安裝;
- ③遥金、通過(guò)命令查看安裝是否成功
>pip show locust >locust -help 查看幫助
- ①、安裝命令
三. 實(shí)例運(yùn)行編寫
ps:安裝的python3.7 版本 import 的變?yōu)榱薍ttpUser 不是之前的 ’HttpLocust‘
ps:由于本地接口需要傳入token
from locust import HttpUser, TaskSet, task
class WebsiteTasks(TaskSet):
def on_start(self):
self.client.post("/chaoxingqiu/account/login_by_password_v_5_1_0/",
{"phoneNumber": "13663644714", "password": "123456"})
# self.client.get("/login?key=00d91e8e0cca2b76f515926a36db68f5&phone=13594347817&passwd=123456")
# @task(2)
# def videoCategory(self):
# self.client.post("/chaoxingqiu/goods/ali_verify_v_5_0_1/", {}, {"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblVzZXJJZCI6ImIyZmFiYzMwNTI1MzM1NTM5MGY3Nzk0NmYwMmJlYTJhIiwidGltZSI6IjE2MDM2OTg5OTAifQ.uBBTCyLC1OMuAGGoEzTZsCKTly4lUFJTQNnByUKx9tE"})
# @task(1)
def videoRecommend(self):
self.client.post("/chaoxingqiu/version/check_version_update_v_5_0_1/", json={"type":0,"versionCode":"1.6.8"}, headers={"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblVzZXJJZCI6ImIyZmFiYzMwNTI1MzM1NTM5MGY3Nzk0NmYwMmJlYTJhIiwidGltZSI6IjE2MDM2OTg5OTAifQ.uBBTCyLC1OMuAGGoEzTZsCKTly4lUFJTQNnByUKx9tE"})
#
# def todayVideo(self):
# self.client.post("/chaoxingqiu/discover/user_online_status_v_5_1_0/", {"type":1},{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblVzZXJJZCI6ImIyZmFiYzMwNTI1MzM1NTM5MGY3Nzk0NmYwMmJlYTJhIiwidGltZSI6IjE2MDM2OTg5OTAifQ.uBBTCyLC1OMuAGGoEzTZsCKTly4lUFJTQNnByUKx9tE"})
#
# def getJoke(self):
# self.client.post("/chaoxingqiu/personal_center/unread_message_display_v_5_0_1/",{"type":5},{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblVzZXJJZCI6ImIyZmFiYzMwNTI1MzM1NTM5MGY3Nzk0NmYwMmJlYTJhIiwidGltZSI6IjE2MDM2OTg5OTAifQ.uBBTCyLC1OMuAGGoEzTZsCKTly4lUFJTQNnByUKx9tE"})
#
# def novelSearchApi(self):
# self.client.post("/chaoxingqiu/personal_center/personal_homepage_display_v_5_1_1/", {},{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblVzZXJJZCI6ImIyZmFiYzMwNTI1MzM1NTM5MGY3Nzk0NmYwMmJlYTJhIiwidGltZSI6IjE2MDM2OTg5OTAifQ.uBBTCyLC1OMuAGGoEzTZsCKTly4lUFJTQNnByUKx9tE"})
#
# tasks = {videoCategory: 2, videoRecommend: 1, todayVideo: 2, getJoke: 3, novelSearchApi: 2} # 與裝飾器效果一致
tasks = {videoRecommend: 1} # 與裝飾器效果一致
class WebsiteUser(HttpUser):
# https://blog.csdn.net/c__chao/article/details/78573737
# task_set = WebsiteTasks # Usage of User.task_set is deprecated since version 1.0. Set the tasks attribute instead (tasks = [WebsiteTasks])
tasks = [WebsiteTasks]
host = "https://api.apiopen.top"
min_wait = 1000
max_wait = 5000
腳本說(shuō)明
新建一個(gè)類WebsiteTasks(TaskSet)浴捆,繼承TaskSet,該類下面寫需要請(qǐng)求的接口以及相關(guān)信息稿械;
self.client調(diào)用get和post方法选泻,和requests一樣;
@task裝飾該方法表示為用戶行為美莫,括號(hào)里面參數(shù)表示該行為的執(zhí)行權(quán)重:數(shù)值越大页眯,執(zhí)行頻率越高,不設(shè)置默認(rèn)是1厢呵;
WebsiteUser()類用于設(shè)置生成負(fù)載的基本屬性:
屬性 | 說(shuō)明 |
---|---|
min_wait | 模擬負(fù)載的任務(wù)之間執(zhí)行時(shí)的最小等待時(shí)間窝撵,單位為毫秒 |
max_wait | 模擬負(fù)載的任務(wù)之間執(zhí)行時(shí)的最大等待時(shí)間,單位為毫秒 |
PS:默認(rèn)情況下襟铭,時(shí)間是在min_wait和max_wait之間隨機(jī)選擇碌奉,但是可以通過(guò)將wait_function設(shè)置為任意函數(shù)來(lái)使用任何用戶定義的時(shí)間分布。
四寒砖、啟動(dòng)locust
1.在文件里面直接執(zhí)行
locust -H http://192.168.1.107:8000 -f demo.py
2赐劣、如果Locust文件位于子目錄下且名稱不是locustfile.py,可以使用-f命令啟動(dòng)上面的示例locust文件:
locust -f demo.py --host=http://192.168.1.107:8000
3哩都、如果要運(yùn)行分布在多個(gè)進(jìn)程中的Locust魁兼,通過(guò)指定-master以下內(nèi)容來(lái)啟動(dòng)主進(jìn)程
locust -f demo.py --master --host=http://192.168.1.107:8000
4、如果要啟動(dòng)任意數(shù)量的從屬進(jìn)程漠嵌,可以通過(guò)-salve命令來(lái)啟動(dòng)locust文件:
locust -f demo.py --salve --host=http://192.168.1.107:8000
5咐汞、如果要運(yùn)行分布式Locust盖呼,必須在啟動(dòng)從機(jī)時(shí)指定主機(jī)(運(yùn)行分布在單臺(tái)機(jī)器上的Locust時(shí)不需要這樣做,因?yàn)橹鳈C(jī)默認(rèn)為127.0.0.1):
locust -f demo.py --slave --master-host=192.168.0.100 --host=https://cnblogs.com
6化撕、啟動(dòng)locust文件成功后几晤,編譯器控制臺(tái)會(huì)顯示如下信息:
[2020-12-10 15:20:41,362] BF-201806010758/INFO/locust.main: Starting web interface at http://0.0.0.0:8089 (accepting connections from all network interfaces)
[2020-12-10 15:20:41,371] BF-201806010758/INFO/locust.main: Starting Locust 1.4.1
五、locust的UI界面
1侯谁、啟動(dòng)界面
ps:Number of users to simulate:設(shè)置模擬的用戶總數(shù)
Hatch rate (users spawned/second):每秒啟動(dòng)的虛擬用戶數(shù)
Start swarming:執(zhí)行l(wèi)ocust腳本
2锌仅、測(cè)試結(jié)果頁(yè)面
Type:請(qǐng)求類型,即接口的請(qǐng)求方法墙贱;
Name:請(qǐng)求路徑;
requests:當(dāng)前已完成的請(qǐng)求數(shù)量贱傀;
fails:當(dāng)前失敗的數(shù)量惨撇;
Median:響應(yīng)時(shí)間的中間值,即50%的響應(yīng)時(shí)間在這個(gè)數(shù)值范圍內(nèi)府寒,單位為毫秒魁衙;
Average:平均響應(yīng)時(shí)間,單位為毫秒株搔;
Min:最小響應(yīng)時(shí)間剖淀,單位為毫秒;
Max:最大響應(yīng)時(shí)間纤房,單位為毫秒纵隔;
Content Size:所有請(qǐng)求的數(shù)據(jù)量,單位為字節(jié)炮姨;
reqs/sec:每秒鐘處理請(qǐng)求的數(shù)量捌刮,即QPS;
3舒岸、模塊說(shuō)明
①绅作、Statistics:類似于jmeter中Listen的聚合報(bào)告;
Charts:測(cè)試結(jié)果變化趨勢(shì)的曲線展示圖俄认,分別為每秒完成的請(qǐng)求數(shù)(RPS)、響應(yīng)時(shí)間洪乍、不同時(shí)間的虛擬用戶數(shù)眯杏;
Failures:失敗請(qǐng)求的展示界面典尾;
④役拴、
Exceptions:異常請(qǐng)求的展示界面;
⑤钾埂、
Download Data:測(cè)試數(shù)據(jù)下載模塊河闰, 提供三種類型的CSV格式的下載科平,分別是:Statistics、responsetime姜性、exceptions瞪慧;