Locust小結


Locust小結

背景

目前網上的教程基本都是1.0之前的,locust叢1.0版本就發生了較多的變化,網上的教程基本不可用。目前locust版本是1.1.1,以下的說明都是針對1.1.1來進行的。

locust適用情景

  • 需要邏輯判斷但不復雜的請求,並持續化存儲
  • 壓測過程要求不嚴格,例如相對復雜的步進式放量
  • 已有專門的壓測指標采集方式,locust提供的監控很雞肋

locust新特性

如果你不想知道改動點,可以之間跳過這塊。

1、HttpLocust的更新

舊版本使用的是TaskSet進行任務或者請求編寫,然后在使用HttpLocust進行任務或者請求聲明,以及基礎屬性配置,一般會進行思考時間、host、task_set設置任務類等;

新版本將HttpLocust重寫成User,並且HttpUser繼承於User,所以推薦使用HttpUser進行任務聲明;

另外TaskSet中的task_set已被刪除,如果仍要使用TaskSet,則需要在HttpUser中使用tasks進行存儲,例
# -*- coding: utf-8 -*-
from locust import HttpUser, task, between, TaskSet


# 采用舊版TaskSet進行定義,不推薦使用,需要在User相關類中定義,才可以被調用
# 補充:SequentialTaskSet是TaskSet子類,作用就是忽略權重,完全根據編寫順序來控制任務執行順序,多用於事務壓測
class TestBaiduSearch2(TaskSet):
    def on_start(self):
        self.header = {
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"
        }
        self.payload = {
            "wd": "selenium",
        }

    @task
    def search(self):
        baidu_response = self.client.get(url="/s", params=self.payload, verify=True, headers=self.header)
        print(baidu_response.url)


# 新版建議都使用HttpUser進行定義
class TestBaiDuSearch(HttpUser):
    host = "https://www.baidu.com"  # 設置host,如果腳本僅是在本地運行或者基本不變的,建議直接腳本固定,反之在啟動運行是加入host參數
    tasks = [TestBaiduSearch2]  # 添加任務
    wait_time = between(100, 200)  # 設置思考時間范圍

    def on_start(self):
        self.payload = {
            "wd": "locust",
        }
        self.header = {
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"
        }

    @task
    def search(self):
        # 默認采用的requests模塊的session,這塊不做贅述,自行查找
        baidu_response = self.client.get(url="/s", params=self.payload, verify=True, headers=self.header)
        print(baidu_response.url)


if __name__ == '__main__':
    import os

    # 啟動腳本,以最大請求5個,每秒步進為1
    os.system("locust -f test11.py --headless -u 5 -r 1")

2、任務標記

請求方法進行標志,@tag進行裝飾,在啟動參數時可以進行選擇啟動或者排除

class TestBaiDuSearch(HttpUser):
    # 命令行啟動就可使用--tags(-T)和--exclude-tags(-E)指定啟動/排除任務
    @task
    @tag("https","baidu")
    def search(self):
        baidu_response = self.client.get(url="/s", params=self.payload, verify=True, headers=self.header)
        print(baidu_response.url)

啟動標志為『https』的任務

locust -f test11.py --host https://www.baidu.com --tags https

3、環境變量變量名修改

LOCUST_MASTER -> LOCUST_MODE_MASTER

LOCUST_SLAVE -> LOCUST_MODE_WORKER

LOCUST_MASTER_PORT -> LOCUST_MASTER_NODE_PORT

LOCUST_MASTER_HOST -> LOCUST_MASTER_NODE_HOST

CSVFILEBASE -> LOCUST_CSV

4、其他變動

4.1 從機的命令行參數改變為--worker,--expect-workers
4.2 無Web模式的命令行參數改變為--headless
4.3 鈎子函數統一使用events進行綁定
...

locust使用

簡單介紹

locust是基於python開發的一個協程請求庫,協程又稱微線程,多個協程可以只運行在一個線程中,由開發者自行選擇切換的時機,所以相對於進程、線程擁有更小的資源切換浪費,但由於是運行在python解析器之上的,所以存在GIL鎖進制,另外默認的網絡請求庫還是requests這種同步庫,所以單進程下並發不會太高。如果想用locust進行並發請求,必定要使用分布式+異步請求庫。

安裝

pip install locust 默認安裝最新版本

常用寫法

# -*- coding: utf-8 -*-
from locust import HttpUser, task, between,tag,SequentialTaskSet,events


# 新版建議都使用HttpUser進行定義
class TestBaiDuSearch(HttpUser):
    wait_time = between(0.1, 0.2)  # 設置請求的思考時間范圍,單位是秒
    # weight = 3       任務類權重,越大優先級越高
    # tasks =[]     建議少用這個,任務集中控制,非要用大概率是你的設計有問題
    
    # 整體啟動執行
    @events.test_start.add_listener
    def on_test_start(**kwargs):
        print("大王我來了!!!")
    
    # 整體結束執行
    @events.test_stop.add_listener
    def on_test_stop(**kwargs):
        print("大王我走了???")

    # 每個請求集啟動之前進行的操作
    def on_start(self):
        self.payloadPref = {
            "wd": "locust",
        }
        self.payloadAuto = {
            "wd": "selenium",
        }
        self.header = {
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"
        }
        print("這就開始了?!")
        
    # 每個請求集結束之后進行的操作
    def on_stop(self):
        print("這就玩完了?!")

    # @task 進行任務標志,里面的數字是權重,權重越大,發起的請求占比越高,如下,相同請求量下,兩者比例約3:1
    # @tag 進行任務標簽注釋,可以選擇啟動或者排查
    @task(3)
    @tag("baidu")
    def searchPref(self):
        baidu_response = self.client.get(url="/s", params=self.payloadPref, verify=True, headers=self.header)
        # print(baidu_response.url)

    @task(1)
    def searchAuto(self):
        baidu_response = self.client.get(url="/s", params=self.payloadAuto, verify=True, headers=self.header)
        # print(baidu_response.url)

if __name__ == '__main__':
    import os

    # 啟動腳本,以最大請求5個,每秒步進為1
    os.system("locust -f test11.py --host https://www.baidu.com --headless -u 5 -r 1")

由於locust默認采用的是requests中的session進行請求發送,所以同樣是支持post、put、head等請求方式,詳見requests官網

配置化啟動

locust不是僅能通過命令行配置啟動,如果每次都要寫那么長的配置,估計出錯的概率也不低,所以locust也提供了配置化啟動的形式,這個真的方便!!例:

locust --config=配置文件路徑

在腳本同級目錄下編寫配置文件,baidu.conf

# 腳本路徑,目前是在同級目錄就直接寫文件名了
# 具體的參數有什么還是參考官網給出  https://docs.locust.io/en/stable/configuration.html
locustfile = testbaidu.py
headless = true
host = http://www.baidu.com
users = 6
hatch-rate = 2
run-time = 1m

命令行執行

locust --config=baidu.conf

分布式啟動

locust支持一主多從的控制模式,這點也對於單機並發也是一個極大的提升,目前基本都是多核多線程的機器,所以分布式可以充分發揮單機的能力。
推薦單機啟動的從機+主機不超過CPU核數,當然你可以試試
首先啟動master,默認占用8089端口用於web界面,5557用於從機交互

locust -f testbaidu.py --master

接連啟動slave

locust -f testbaidu.py --worker --master-host=127.0.0.1 #此處本地,遠程的話使用對應ip即可

瀏覽器打開 http://127.0.0.1:8089,可見右上角,WORKERS顯示的數量與啟動的從機數量一致。
注意,界面填寫的User量級是總量會均分給每個從機。

locust壓測大殺器

前面也多次講到了locust如果采用了HttpUser,則默認的請求庫是使用requests,requests是同步阻塞的請求庫,對於壓測來說,還是很致命的,每個請求發送完成之后都在響應的回來,即是你機器配置好,也無法充分發揮。
所以locust提供了一個異步請求庫,對於代碼我們只需將HttpUser改為FastHttpUser即可,前提導入

from locust.contrib.fasthttp import FastHttpUser

另注意,FastHttpUser提供的geventhttpclient其實有坑,比如post請求的data就要求只能是String類型,相對於requests請求還是不太好用。

locust的步進模式

用過jmeter的同學應該都知道,壓測一般會采用逐級放量的形式進行請求發送。
同樣locust也提供了這種步進默認。

--step-load  啟用步進模式
--step-users    每級的用戶增量
--step-time     增量間隔

locust -f --headless -u 1000 -r 100 --run-time 30m --step-load --step-users 300 --step-time 1m
無web界面啟動locust,設置總用戶數1000,每秒增量100個用戶,運行總時長30分鍾,啟動步進模式,步進用戶300,維持每個步進模式時間為1分鍾

當達到300用戶時會維持一分鍾,然后在持續增量用戶,達到600在維持一分鍾,以此類推

locust的其他功能
1、自定義請求對象 https://docs.locust.io/en/stable/testing-other-systems.html

2、擴展Web界面 https://docs.locust.io/en/stable/extending-locust.html

3、將locust作為庫來進行使用,調用內部的協程api https://docs.locust.io/en/stable/use-as-lib.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM