python 并发请求(设定吞吐量)

需求是,每秒发起请求(异步)

前提,压测接口,response time 为3-5秒

 1 from flask import Flask
 2 import random
 3 import time
 4 
 5 app = Flask(__name__)
 6 
 7 
 8 @app.route('/')
 9 def hello_world():
10     return 'Hello, World!'
11 
12 
13 @app.route('/time', methods=['POST', 'GET'])
14 def atime():
15     a = random.randint(3, 5)
16     time.sleep(a)
17     s = 'time ---->' + str(a)
18     if a == 5:
19         s = 1 / 0
20     return s
21 
22 
23 if __name__ == '__main__':
24     app.run()

请求地址:http://127.0.0.1:5000/time

 

1.尝试使用jmeter压测,发现只能做到同步(获得结果后再发起请求)

 2.python实现

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

from threading import Thread
import requests
# import matplotlib.pyplot as plt
import datetime
import time
import numpy as np
import json


class ThreadTest(Thread):
    def __init__(self, func, args=()):
        '''
      :param func: 被测试的函数
      :param args: 被测试的函数的返回值
      '''
        super(ThreadTest, self).__init__()
        self.func = func
        self.args = args

    def run(self) -> None:
        self.result = self.func(*self.args)

    def getResult(self):
        try:
            return self.result
        except BaseException as e:
            return e.args[0]


def baiDu(url, code, seconds):
    '''
   :param code: 状态码
   :param seconds: 请求响应时间
   :return:
   '''
    r = requests.get(url=url)
    code = r.status_code
    seconds = r.elapsed.total_seconds()
    return code, seconds


def calculationTime(startTime, endTime):
    '''计算两个时间之差,单位是秒'''
    return (endTime - startTime).seconds + (endTime - startTime).days*24*60*60


def getResult(seconds):
    '''获取服务端的响应时间信息'''
    data = {
        'Max': sorted(seconds)[-1],
        'Min': sorted(seconds)[0],
        'Median': np.median(seconds),
        '99%Line': np.percentile(seconds, 99),
        '95%Line': np.percentile(seconds, 95),
        '90%Line': np.percentile(seconds, 90)
    }
    return data


def highConcurrent(url, count, countPerS):
    '''
   对服务端发送高并发的请求
   :param cout: 并发数
   :return:
   '''
    global throughput
    startTime = datetime.datetime.now()
    sum = 0
    list_count = list()
    tasks = list()
    results = list()
    # 失败的信息
    fails = []
    # 成功任务数
    success = []
    codes = list()
    seconds = list()

    for i in range(int(count)):
        # DispatchIDS = ['CMA01', 'DAA03', 'MPL0A', 'DCA01', 'CUE0A', 'DKA03', 'DRA51', 'MAA01', 'RAA52', 'WHJ02']
        # import random
        # DispatchID = random.choice(DispatchIDS)
        # DispatchID = DispatchIDS[i % 10]
        # url = 'http://10.50.45.240:8080/rtd/92?DispatchID=' + DispatchID
        import random
        alamRandint = random.randint(3,5)
        url = "http://127.0.0.1:5000/time/"+ str(alamRandint)
        t = ThreadTest(baiDu, args=(url, i, i))
        tasks.append(t)
        t.start()
        print(datetime.datetime.now())
        time.sleep(1 / countPerS)



    for t in tasks:
        t.join()
        if t.getResult()[0] != 200:
            fails.append(t.getResult())
        results.append(t.getResult())

    for item in results:
        codes.append(item[0])
        seconds.append(item[1])
    for i in range(len(codes)):
        list_count.append(i)

    # 生成可视化的趋势图
    # fig, ax = plt.subplots()
    # ax.plot(list_count, seconds)
    # ax.set(xlabel='number of times', ylabel='Request time-consuming',
    #        title='olap continuous request response time (seconds)')
    # ax.grid()
    # fig.savefig('olap.png')
    # plt.show()
    # print("seconds ==",seconds)
    # print("list_count ==", list_count)
    # print("fails ==", fails) #[]
    # print("success ==",success) #[]
    # print("results ==", results)

    for i in seconds:
        # print('i', i)
        # print('type(i)', type(i))
        if type(i) == type(1.0):
            sum += i
        else:
            sum += 0
            # len(list_count)-len(fails)
    # print('sum', sum)
    # print("len(list_count)", len(list_count))
    rate = sum / len(list_count)
    endTime = datetime.datetime.now()
    # print('\n总共持续时间:\n',endTime-startTime)
    totalTime = calculationTime(startTime=startTime, endTime=endTime)
    # print('totalTime', totalTime)
    if totalTime < 1:
        totalTime = 1
    # 吞吐量的计算
    try:
        print("float(len(list_count) ", float(len(list_count)))
        print("totalTime", totalTime)
        throughput = float(len(list_count) / totalTime)
    except Exception as e:
        print(e.args[0])
    getResult(seconds=seconds)
    errorRate = 0
    if len(fails) == 0:
        errorRate = 0.00
    else:
        errorRate = len(fails) / len(tasks) * 100
    throughput = str(throughput) + '/S'
    timeData = getResult(seconds=seconds)
    dict1 = {
        '吞吐量(tps)': throughput,
        '平均响应时间(s)': rate,
        '响应时间(s)': timeData,
        '请求总数': len(list_count),
        '错误数': len(fails),
        '错误率(%)': errorRate,
        '执行时间(s)': totalTime
    }
    return json.dumps(dict1, indent=True, ensure_ascii=False)


if __name__ == '__main__':
    DispatchIDS = ['CMA01', 'DAA03', 'MPL0A', 'DCA01', 'CUE0A', 'DKA03', 'DRA51', 'MAA01', 'RAA52', 'WHJ02']
    url = 'http://10.50.45.240:8080/rtd/92?DispatchID='

    days = 1
    hours = 1
    minutes = 1
    seconds = 10
    countPerS = 1  # 每秒请求数量<br>

    counts = days * 24 * 60 * 60 + hours * 60 * 60 + minutes * 60 + seconds
    counts = counts * countPerS
    # print(counts)
    print(highConcurrent(url=url, count=counts, countPerS=countPerS))

'''
2023-07-11 11:30:54.941397
2023-07-11 11:30:55.455986
....
2023-07-11 11:31:24.244365
2023-07-11 11:31:24.750616
{
 "吞吐量(tps)": "1.8181818181818181/S",
 "平均响应时间(s)": 3.963214083333334,
 "响应时间(s)": {
  "Max": 5.02367,
  "Min": 3.005881,
  "Median": 4.009576,
  "99%Line": 5.01937067,
  "95%Line": 5.013791149999999,
  "90%Line": 5.0105454
 },
 "请求总数": 60,
 "错误数": 0,
 "错误率(%)": 0.0,
 "执行时间(s)": 33
}

nohup python my.py >> my.log 2>&1 &
# 等价于下面两行的内容
nohup python my.py 1>> my.log &
nohup python my.py 2>> my.log &
'''

  

  

返回结果如下

2023-07-08 16:24:48.524257
2023-07-08 16:24:49.027055
2023-07-08 16:24:49.539939
.......
2023-07-08 17:25:57.709663
2023-07-08 17:25:58.225109

{
 "吞吐量(tps)": "1.9599782194391506/S",
 "平均响应时间(s)": 4.006165397416303,
 "响应时间(s)": {
  "Max": 5.036263,
  "Min": 3.002034,
  "Median": 4.009866,
  "99%Line": 5.01809934,
  "95%Line": 5.0155911,
  "90%Line": 5.0130394
 },
 "请求总数": 7199,
 "错误数": 2368,
 "错误率(%)": 32.893457424642314,
 "执行时间(s)": 3673
}

Process finished with exit code 0

  运行方式(后台运行,实时查看数据)

nohup python -u alamThreadRequests.py >> alam0712.log 2>&1 &

tail -f alam0712.log

  

posted @ 2023-07-08 20:01  AlamZ  阅读(466)  评论(0)    收藏  举报