Locust的介紹
Locust是一個python的性能測試工具,你可以通過寫python腳本的方式來對web接口進行負載測試。
Locust的安裝
首先你要安裝python2.6以上版本,而且有pip工具。之后打開命令行,分別安裝locustio和pyzmq(命令如下):
pip install locustio
pip install pyzmq
PS:如果是python3,不能使用pip安裝目前。需要在github上下載locust項目包到本地,然后在包路徑下執行命令安裝:
python setup.py install
Locust腳本編寫
接下來我們拿兩個接口做一下測試,編寫腳本如下(每一步都有注釋)。我來解釋一下,首先我們要import進來三個類,分別是HttpLocust(用來模擬發請求的類)、TaskSet(顧名思義,任務集)、task(任務類)。額外的,為了方便觀察接口測試的執行結果,我引入了json類用來解析web接口的返回值。我還引入了subprocess類用來執行一下shell命令,自啟動Locust。這里有三個類,一個是UserBehavior(名字隨便起,但傳入TaskSet參數,說明這是一個包含了任務集的類),里面on_start函數可有可無,他會先于所有task函數運行。剩下被@task裝飾器裝飾的方法都是任務方法,里面包含了待請求的接口等信息,傳入的參數代表了權重,如下所示兩個被@task裝飾的方法分別傳入1和2,這意味著每3個人里有兩個人會有1個模擬用戶執行list_header方法,2個模擬用戶執行list_goods方法。這個參數你也可以不傳入,那就意味著模擬用戶會隨機訪問所有被@task裝飾的方法。這里面我對于每個接口的返回值都做了一下判斷,首先將返回的字符串轉成json格式并獲取返回字段result的值,如果不是100就用Locust自帶的報錯方法打印出錯信息;另兩個類是HttpLocust類(仍然是名字隨便起但傳入參數必須得是HttpLocust),是用來模擬用戶的類,包含了一些模擬用戶信息,其中task_set變量的值用來指定模擬用戶所對應要完成的TaskSet類中包含的請求,min_wait和max_wait(最小等待時間和最大等待時間用來模擬用戶每兩步操作之間的間隔時間,這里也就是模擬用戶每執行兩個請求之間所間隔的時間)。對Locust類我們可以指定權重,對weight變量的值進行指定。如下所示,兩個Locust類的權重分別為1和3,這意味著兩個Locust類的模擬用戶人數為1:3的關系。最后我加了一個main函數用來執行shell命令,這個shell命令也可以不再本文件中執行,如果寫在腳本中的話,直接在命令行中調用該python文件即可,如果不寫在腳本中(注釋掉最后兩行),則需要在命令行終端里對Locust項目進行啟動。
from locust import HttpLocust,TaskSet,task
import subprocess
import json
#This is the TaskSet class.
class UserBehavior(TaskSet):
? ? #Execute before any task.
? ? def on_start(self):
? ? ? ? pass
? ? #the @task takes an optional weight argument.
? ? @task(1)
? ? def list_header(self):
? ? ? ? r = self.client.get("/homepage/list_header.html")
? ? ? ? if json.loads((r.content))["result"] != 100:
? ? ? ? ? ? r.failure("Got wrong response:"+r.content)
? ? @task(2)
? ? def list_goods(self):
? ? ? ? r = self.client.get("/homepage/list_goods.html")
? ? ? ? if json.loads((r.content))["result"] != 100:
? ? ? ? ? ? r.failure("Got wrong response:"+r.content)
#This is one HttpLocust class.
class WebUserLocust(HttpLocust):
? ? #Speicify the weight of the locust.
? ? weight = 1
? ? #The taskset class name is the value of the task_set.
? ? task_set = UserBehavior
? ? #Wait time between the execution of tasks.
? ? min_wait = 5000
? ? max_wait = 15000
#This is another HttpLocust class.
class MobileUserLocust(HttpLocust):
? ? weight = 3
? ? task_set = UserBehavior
? ? min_wait = 3000
? ? max_wait = 6000
#if __name__ == '__main__':
#? ? subprocess.Popen('locust -f .\locust_test_1.py --host=http://api.g.caipiao.163.com', shell=True)
Locust的啟動
對Locust項目的啟動,我們可以在命令行終端中執行以下命令:
locust -f .\locust_test_1.py --host=http://api.g.caipiao.163.com
這里的“-f”指定了要執行的python文件路徑,“--host”指定了模擬用戶請求接口的host名。執行該命令,Locust項目就啟動了。如果遇到下面的錯誤,注意[Errorno 10048]那行,可以看出端口8089被占用導致Locust項目啟動失敗,這里我們需要找到對應占用了8089端口的進程并殺掉:
為了檢測占用端口的進程我寫了一個PowerShell小腳本:
function checkPid($result,$port){
? ? $port = $port.split(":")[1]
? ? if(($result.split())[6].split(":")[($result.split())[6].split(":").Count-1] -eq $port){
? ? ? ? $tPid = ($result.split())[($result.split()).count-1]
? ? ? ? if($tPid -ne "0"){
? ? ? ? ? ? Write-Host "您查詢的端口被以下程序占用:" -ForegroundColor Red
? ? ? ? ? ? $target = tasklist|findstr $tPid
? ? ? ? ? ? Write-Host $target
? ? ? ? ? ? $sig = $true
? ? ? ? }else{
? ? ? ? ? ? $sig = $false
? ? ? ? }
? ? }else{
? ? ? ? $sig = $false
? ? }
? ? $sig
}
function checkPort($port){
? ? $port = ":" + $port
? ? $results = netstat -ano|findstr $port
? ? if($results.count -gt 0){
? ? ? ? if($results.count -eq 1){
? ? ? ? ? ? $sig = checkPid $results $port
? ? ? ? ? ? if($sig -eq $false){
? ? ? ? ? ? ? ? Write-Host "您所查詢的端口未被占用!" -ForegroundColor Green
? ? ? ? ? ? }
? ? ? ? }else{
? ? ? ? ? ? foreach($result in $results){
? ? ? ? ? ? ? ? if($result){
? ? ? ? ? ? ? ? ? $sig = checkPid $result $port
? ? ? ? ? ? ? ? ? if($sig -eq $true){
? ? ? ? ? ? ? ? ? ? ? break
? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? if($sig -eq $false){
? ? ? ? ? ? ? ? Write-Host "您所查詢的端口未被占用!" -ForegroundColor Green? ? ? ?
? ? ? ? ? ? }
? ? ? ? }
? ? }else{
? ? ? ? Write-Host "您所查詢的端口未被占用!" -ForegroundColor Green
? ? }
}
$port = $null
while($port -ne "exit()"){
? ? $port = Read-Host "請輸入要查詢的端口號"
? ? if($port -eq "exit()"){
? ? ? ? break
? ? }
? ? checkPort $port
}
運行該腳本,輸入端口號8089我們可以看出python.exe進程占用了該端口號:
然后我們在PowerShell中殺掉該進程,再啟動Locust項目,就成功了(如下):
接下來就可以在瀏覽器中訪問我們的locust頁面來完成負載測試了,如果不想通過瀏覽器來設置完成負載測試,純粹命令行模式也是支持的,輸入以下命令:
locust-f.\locust_test_1.py --host='http://api.winyyg.com' --no-web -c 1000 -r 10 -n 1000
接下來負載測試就會自動執行,按“ctrl+c”結束負載測試:
對于命令行中的參數的解釋:--no-web是用來選擇無瀏覽器模式,-c后面接的是模擬用戶數,-r后面接的每秒模擬用戶并發數,-n后面接的是模擬請求數。
Locust負載測試
在瀏覽器中輸入“http://localhost:8089/”訪問,會看到如下頁面:
這里我們按提示輸入要模擬的用戶總數和每秒鐘并發的用戶數量,點擊“Start swarming”就可以運行負載測試了:
點擊“STOP”按鈕停止負載測試,現在STATUS為“STOPPED”,點擊“New test”可以進行一個新的測試: