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实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | #!/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 & ''' |
返回结果如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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 |
运行方式(后台运行,实时查看数据)
1 2 3 | nohup python - u alamThreadRequests.py >> alam0712.log 2 >& 1 & tail - f alam0712.log |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)