壓測工具Locuse的使用


我是聽朋友提起的"蝗蟲"(Locust),然而她不想用python,我就拿來試一試~

http的 各種壓測工具也已經太多了,所以主要是試試locust在當前比較流行的rpc協議上的效果

 

目的 -- 調研locust應用於grpc協議

服務 -- grpc的helloworld

一  環境准備

1 需要python環境,我使用的是python2.7

2 安裝locust

pip install locustio
pip install pyzmq        // 分布式運行多個起壓locust時使用
pip install gevent==1.1 // 據說是因為升級后的gevent不能很好的支持python2系列?
locust -h                // 查看可用參數

二 被測服務編寫

1 windows的web界面測試 

① python代碼,寫好保存在為test_001.py

from locust import HttpLocust,TaskSet,task
import subprocess
import json 

class UserBehavior(TaskSet):
    def on_start(self):
        pass

    @task(1)
    def list_header(self):
        r = self.client.get("/")

class WebUserLocust(HttpLocust):
    weight = 1
    task_set = UserBehavior
    host = "http://www.baidu.com"
    min_wait = 5000
    max_wait = 15000

② 在命令行執行 

locust -f E:\Work\PyCharmTest\locusttest\test_001.py

③ 打開瀏覽器,輸入網址:localhost:8089       (locust 的默認監聽端口為8089)

     在顯示頁面輸入模擬用戶數和每個用戶的req/s,點擊 start swarming 即可開始 

④ 需要手動結束,在頁面點擊stop或者在命令行ctrl+c退出locust啟動命令,即可查看結果如下:

  顯示總請求數、失敗請求數、請求的耗時分布、qps、傳輸字節數等

2 linux運行

① python代碼 -- 此處寫的proto文件,helloworld

syntax = "proto3";
option java_package = "io.grpc.examples";
package helloworld;

// The greeter service definition.
service Greeter {
    // Sends a greeting
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request meesage containing the user'name.
message HelloRequest {
    string name = 1;
}

// The response message containing the greetings
message HelloReply {
    string message = 1;    
}

② 轉成python

執行如下命令,生成helloworld_pb2.py和helloworld_pb2_grpc兩個文件

protoc  --python_out=. helloworld.proto

③ 啟動helloworld的server(該部分隨意,根據實際設置)

    該部分用的python的server,啟動端口設置為50052 

import sys
import grpc
import time
sys.path.append("..")

from concurrent import futures
from helloworld.helloworld import helloworld_pb2, helloworld_pb2_grpc

_ONE_DAY_IN_SECONDS = 60 * 60 * 24
_HOST = 'localhost'
_PORT = '50052'
class Greeter(helloworld_pb2_grpc.GreeterServicer):
    def SayHello(self, request, context):
        str = request.name
        return helloworld_pb2.HelloReply(message='hello, '+str)

def serve():
    grpcServer = grpc.server(futures.ThreadPoolExecutor(max_workers=4))
    helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), grpcServer)
    grpcServer.add_insecure_port(_HOST + ':' + _PORT)
    grpcServer.start()

    try:
        while True:
            time.sleep(_ONE_DAY_IN_SECONDS)
    except KeyboardInterrupt:
        grpcServer.stop(0)

if __name__ == '__main__':
    serve()

④ 編寫locust文件,對端口50052的服務進行壓測,locust文件如下:

    我抄的,從這兒:http://codegist.net/code/grpc%20locust/

#!/usr/bin/env python 2.7
# -*- coding:utf-8 -*-

import os,sys, argparse
sys.path.append("..")
import grpc
import json
import requests
import time
import random
import string

from helloworld.helloworld import helloworld_pb2, helloworld_pb2_grpc
from locust import Locust, TaskSet, task, events
from locust.stats import RequestStats
from locust.events import EventHook


def parse_arguments():
    parser = argparse.ArgumentParser(prog='locust')
    parser.add_argument('--hatch_rate')
    parser.add_argument('--master', action='store_true')
    args, unknown = parser.parse_known_args()
    opts = vars(args)
    return args.host, int(args.clients), int(args.hatch_rate)

#HOST, MAX_USERS_NUMBER, USERS_PRE_SECOND = parse_arguments()
HOST, MAX_USERS_NUMBER, USERS_PRE_SECOND = '127.0.0.1:50052', 1, 10

# 分布式,需要啟多台壓測時,有一個master,其余為slave slaves_connect
= [] slave_report = EventHook() ALL_SLAVES_CONNECTED = True SLAVES_NUMBER = 0 def on_my_event(client_id, data): global ALL_SLAVES_CONNECTED if not ALL_SLAVES_CONNECTED: slaves_connect.append(client_id) if len(slaves_connect) == SLAVES_NUMBER: print "All Slaves Connected" ALL_SLAVES_CONNECTED = True # print events.slave_report._handlers header = {'Content-Type': 'application/x-www-form-urlencoded'} import resource rsrc = resource.RLIMIT_NOFILE soft, hard = resource.getrlimit(rsrc) print 'RLIMIT_NOFILE soft limit starts as : ', soft soft, hard = resource.getrlimit(rsrc) print 'RLIMIT_NOFILE soft limit change to: ', soft events.slave_report += on_my_event class GrpcLocust(Locust): def __init__(self, *args, **kwargs): super(GrpcLocust, self).__init__(*args, **kwargs) class ApiUser(GrpcLocust): min_wait = 90 max_wait = 110 stop_timeout = 100000 class task_set(TaskSet): def getEnviron(self, key, default): if key in os.environ: return os.environ[key] else: return default def getToken(self): consumer_key = self.getEnviron('SELDON_OAUTH_KEY', 'oauthkey') consumer_secret = self.getEnviron('SELDON_OAUTH_SECRET', 'oauthsecret') params = {} params["consumer_key"] = consumer_key params["consumer_secret"] = consumer_secret url = self.oauth_endpoint + "/token" r = requests.get(url, params=params) if r.status_code == requests.codes.ok: j = json.loads(r.text) # print j return j["access_token"] else: print "failed call to get token" return None def on_start(self): # print "on start" # self.oauth_endpoint = self.getEnviron('SELDON_OAUTH_ENDPOINT', "http://127.0.0.1:50053") # self.token = self.getToken() self.grpc_endpoint = self.getEnviron('SELDON_GRPC_ENDPOINT', "127.0.0.1:50052") self.data_size = int(self.getEnviron('SELDON_DEFAULT_DATA_SIZE', "784")) @task def get_prediction(self): conn = grpc.insecure_channel(self.grpc_endpoint) client = helloworld_pb2_grpc.GreeterStub(conn) start_time = time.time() name = string.join(random.sample(['a','b','c','d','e','f','g'], 3)).replace(" ","") request = helloworld_pb2.HelloRequest(name=name) try: reply = client.SayHello(request) except Exception,e: total_time = int((time.time() - start_time) * 1000) events.request_failure.fire(request_type="grpc", name=HOST, response_time=total_time, exception=e) else: total_time = int((time.time() - start_time) * 1000) events.request_success.fire(request_type="grpc", name=HOST, response_time=total_time, response_length=0)

⑤ 啟動locust,查看結果

locust --help可以看到命令的使用幫助。注意 -c -n -r 參數的使用需要配合 --no-web

 

 三 問題及解決

問題倒是有,但是我沒解決,我不知道這個起壓的req怎么設置的

原本以為 -c  模擬用戶數  -r 每個用戶發出的秒請求數 --- 那么服務每秒承受的壓力就應該為-c * -r 

但是我跑出來的結果確實這樣的,特別像是-c * 10 ,大臉懵逼了

 

 

 

 




免責聲明!

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



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