locust分布式压测的Step Load及no web模式下的报表自动生成
Running Locust in Step Load Mode
If you want to monitor your service performance with different user load and probe the max tps that can be achieved, you can run Locust with Step Load enabled with --step-load:
如果你想分阶段递增并发用户数压测,找到系统最大的QPS,你可以用--step-load --step-users XX --step-time XX命令,不用再手动去增加用户数和压测时间。
譬如:
locust -f D:\api_locust\fm_api\locust_api\XXX.py --master --master-bind-port 9800 --headless -u 800 -r 50 --expect-workers 10 -t 50m -s 10 --step-load --step-users 200 --step-time 10m --csv D:\locustlog\
总共发起800并发请求,每秒启动50个用户,当启动到200用户数时,持续运行10分钟,运行步骤大致如下:
(1)4s启动到200
(2)200用户数:10分钟
(3)4s启动到400
(4)400用户数:10分钟
(5)4s启动到600
(6)600用户数:10分钟
(7)4s启动到800
(8)800用户数:10分钟
(9)800用户数:50-40=10分钟(小于10分钟)
压测结果如图:
可以得出系统qps最大也就550左右,后边随着并发数提升没有提升,唯一提升是平均响应时间。
通过 --step-load --step-users这样的命令就不用再折腾弄命令了。
关于压测结果图的生成,也很简单的,上面的压测命令会把压测的历史记录写到csv文件里,
读取csv文件再生成报表即可:
python用到的模块pyecharts
pyecharts文档地址:http://pyecharts.org/#/zh-cn/intro
贴个代码示例:
1 # -*- coding = utf-8 -*-
2 # ------------------------------
3 # @time: 2020/8/15 16:05
4 # @Author: drew_gg
5 # @File: deal_csv.py
6 # @Software: api_locust
7 # ------------------------------
8
9 import os
10 import time
11 import csv
12 import datetime
13 from pyecharts.charts import Line
14 from pyecharts import options as opts
15 from pyecharts.globals import ThemeType
16
17 """
18 # pyecharts使用文档
19 # http://pyecharts.org/#/zh-cn/intro
20 """
21
22 pl = os.getcwd().split('api_locust')
23 path_html = pl[0] + 'api_locust\\resource\\html\\'
24
25
26 def report(interface_name, history_csv, stats_csv):
27 """
28 locust生成报表
29 :param interface_name:
30 :param history_csv:
31 :param stats_csv:
32 :return:
33 """
34 tm = []
35 uc = []
36 qps = []
37 fps = []
38 avg_time = []
39 all_r = ''
40 all_qps = ''
41 all_avg_time = ''
42 with open(history_csv, 'r') as f:
43 hc = csv.reader(f)
44 for x, i in enumerate(list(hc)):
45 if i:
46 if x != 0:
47 tm.append(time.strftime('%H:%M:%S', time.localtime(int(i[0]))))
48 uc.append(str(round(float(i[1]), 2)))
49 qps.append(str(round(float(i[4]), 2)))
50 fps.append(str(round(float(i[5]), 2)))
51 avg_time.append(str(round(float(i[20]), 2)))
52 with open(stats_csv, 'r') as f:
53 sc = csv.reader(f)
54 for x, i in enumerate(list(sc)):
55 if x != 0 and len(i) != 0:
56 all_r = str(i[2])
57 all_qps = str(round(float(i[9]), 2))
58 all_avg_time = str(round(float(i[5]), 2))
59 locust_title = "[{0}]压测情况:[ARC:{1}, QPS: {2}, AVT: {3}]".format(interface_name, all_r, all_qps, all_avg_time)
60 locust_html_name = path_html + interface_name + str(datetime.datetime.now().strftime('%m%d%H%M%S')) + '.html'
61 line = (
62 Line(init_opts=opts.InitOpts(theme=ThemeType.CHALK, width="1800px", height="800px"))
63 .add_xaxis(tm)
64 .add_yaxis('user', uc, is_smooth=True)
65 .add_yaxis('qps', qps, is_smooth=True)
66 .add_yaxis('fps', fps, is_smooth=True)
67 .add_yaxis('avg_t', avg_time, is_smooth=True)
68 .set_global_opts(
69 title_opts=opts.TitleOpts(title=locust_title),
70 tooltip_opts=opts.TooltipOpts(trigger="axis"),
71 toolbox_opts=opts.ToolboxOpts(is_show=True, orient="vertical", pos_left="1%", pos_top="10%"),
72 xaxis_opts=opts.AxisOpts(type_="category", boundary_gap=False,),
73 )
74 )
75 line.render(locust_html_name)
76
77
78 if __name__ == "__main__":
79 stats = "D:\\api_locust\\resource\\csv\\locust_exhibition_home.py0826095139_stats.csv"
80 history = "D:\\api_locust\\resource\\csv\\locust_exhibition_home.py0826095139_stats_history.csv"
81 report('a', history, stats)
关于报表的生成,不懂的自行去文档地址仔细研究研究,挺全的,各种报表样式都有。
另外,如果是分布式压测的话,不要手动去启动命令,自己写个py去自动创建生成多好:
1 # -*- coding = utf-8 -*-
2 # ------------------------------
3 # @time: 2020/8/15 16:05
4 # @Author: drew_gg
5 # @File: locust_main.py
6 # @Software: api_locust
7 # ------------------------------
8
9 import datetime
10 import subprocess
11
12
13 class CoverLocust:
14 """
15 封面压测封装类
16 """
17 def __init__(self, ltp):
18 """
19 初始化压测参数
20 :param ltp: 参数字典
21 """
22 self.user = ltp['user']
23 self.r = ltp['r']
24 self.slave = ltp['slave']
25 self.m_time = ltp['m_time']
26 self.port = ltp['port']
27 self.master_host = ltp['master_host']
28 self.csv = ltp['csv']
29 self.master_script = ltp['master_script']
30 self.slave_script = ltp['slave_script']
31 self.step_u = ltp['step_u']
32 self.step_t = ltp['step_t']
33 # 定义csv文件名称
34 self.csv_name = ltp["master_script"].split('\\')[-1] + str(datetime.datetime.now().strftime('%m%d%H%M%S'))
35 self.csv_path = ltp['csv'] + self.csv_name
36 # 输出压测结果目录文件
37 self.stats_history_csv = self.csv_path + '_stats_history.csv'
38 self.stats_csv = self.csv_path + '_stats.csv'
39 self.failures_csv = self.csv_path + '_failures.csv'
40
41 # 生成master命令
42 def locust_master(self):
43 """
44 运行master指令
45 :return:
46 """
47 master_cmd = "locust -f %s --master --master-bind-port %s --headless " % (self.master_script, self.port)
48 master_pra = "-u %s -r %s --expect-workers %s -t %s -s 10 --step-load --step-users %s --step-time %s --csv %s "\
49 % (self.user, self.r, self.slave, self.m_time, self.step_u, self.step_t, self.csv_path)
50 master_cmd = master_cmd + master_pra
51 print(master_cmd)
52 subprocess.Popen(master_cmd, creationflags=subprocess.CREATE_NEW_CONSOLE)
53 return self.stats_history_csv, self.stats_csv, self.failures_csv, self.csv_name
54
55 # 生成slave命令
56 def locust_slave(self, slave_num):
57 """
58 运行slave指令
59 :param slave_num:
60 :return:
61 """
62 slave_cmd = "locust -f %s --master-host %s --master-port %s --headless --worker" % (self.slave_script, self.master_host, self.port)
63 print(slave_cmd)
64 for i in range(slave_num):
65 subprocess.Popen(slave_cmd, creationflags=subprocess.CREATE_NEW_CONSOLE)
66
67 # 杀掉压测进程
68 @classmethod
69 def close_process(cls):
70 """
71 杀掉命令进程
72 :return:
73 """
74 import os
75 os.system('taskkill /IM locust.exe /F')
1 # -*- coding = utf-8 -*-
2 # ------------------------------
3 # @time: 2020/8/18 20:36
4 # @Author: drew_gg
5 # @File: locust_run.py
6 # @Software: api_locust
7 # ------------------------------
8
9 import os
10 import time
11 from run_locust import locust_main as locust_m
12 from locust_common.common_excel import deal_csv as report
13
14 pl = os.getcwd().split('api_locust')
15 path_csv = pl[0] + 'api_locust\\resource\\csv\\'
16 path_script = pl[0] + 'api_locust\\locust_view\\kbh_api\\locust_api\\'
17 script_name = "locust_exhibition_home.py"
18
19 # ************************************需维护更改的参数****************************#
20 # 并发数
21 user = 1400
22 # 每秒启动用户数
23 rate = 200
24 # 分布式压测启动的slave数量
25 num_slave = 10
26 # 本次压测执行的时长:h,m,s
27 run_time = '25m'
28 # master所在host/ip
29 master_host = "10.111.53.123"
30 # master 执行脚本
31 master_script = path_script + script_name
32 # slave 执行脚本
33 slave_script = path_script + script_name
34 # # csv存储文件的目录
35 # csv_path = path_csv + script_name.split('.')[0] + '_log\\'
36 # 递压用户数
37 step_user = 400
38 # 递压持续时间
39 step_time = '5m'
40 # ************************************需维护更改的参数****************************#
41
42
43 locust_p = {
44 'user': user,
45 "r": rate,
46 "slave": num_slave,
47 "m_time": run_time,
48 "port": 9800,
49 "master_host": master_host,
50 "csv": path_csv,
51 "master_script": master_script,
52 "slave_script": slave_script,
53 "step_u": step_user,
54 "step_t": step_time
55 }
56
57 if __name__ == "__main__":
58
59 # *****************执行脚本标识*******************#
60 sign = "master"
61 # sign = "slave"
62 # *****************执行脚本标识*******************#
63 lm = locust_m.CoverLocust(locust_p)
64 lm.close_process()
65 if sign == "master":
66 # 启动master
67 history_csv, stats_csv, failures_csv, csv_name = lm.locust_master()
68 sleep_time = int(run_time[:-1])
69 # 延迟30s读取csv文件
70 if run_time[-1] == 'h':
71 sleep_time = sleep_time * 60 * 60 + 30
72 if run_time[-1] == 'm':
73 sleep_time = sleep_time * 60 + 30
74 if run_time[-1] == 's':
75 sleep_time = sleep_time + 30
76 time.sleep(sleep_time)
77 # 生成报表
78 report.report(script_name.split('.')[0], history_csv, stats_csv)
79 if sign == "slave":
80 # 启动slave 分多台跑的话需要用num_slave除以台数
81 slave_num = int(num_slave/2)
82 lm.locust_slave(slave_num)
这样要修改啥,直接修改就行,也可以自己写个页面,点一下按钮就可以压测。
上面的这个压测结果图:
这个说明QPS还有升高的空间,目前的并发数还没到达瓶颈,还得再提升并发数【平均响应时间没有急剧提升】。当然,这个地方设置的between(0,0.5),
所以会出现800的并发结果qps达到960以上。
Locust QQ 群:
locust分布式压测的Step Load及no web模式下的报表自动生成的更多相关文章
- wrk,ab,locust,Jmeter 压测结果比较
背景: 项目需要对一批接口进行压测,要求是接口的QPS(Quest Per Second每秒请求数)达到6万以上由于楼主一直使用的压力测试工具是jmeter,但是jmeter单台电脑无法达到6万的QP ...
- 案例 | 荔枝微课基于 kubernetes 搭建分布式压测系统
王诚强,荔枝微课基础架构负责人.热衷于基础技术研发推广,致力于提供稳定高效的基础架构,推进了荔枝微课集群化从0到1的发展,云原生架构持续演进的实践者. 本文根据2021年4月10日深圳站举办的[腾讯云 ...
- jmeter分布式压测
stop.sh需要跑Jmeter的服务器上安装Jmeteryum install lrzsz 安装rz.sz命令rz jemter的压缩包 拷贝到/usr/local/tools下面unzip apa ...
- jmeter 分布式压测(Linux)
之前一篇博文写的是如何在Linux上使用jmeter压测,这篇介绍下Linux上jmeter的分布式压测. 和windows上的分布式类似,需要配置agent节点和控制机 一.Agent节点配置 1. ...
- jmeter 分布式压测(windows)
单台压测机通常会遇到客户端瓶颈,受制于客户机的性能.可能由于网络带宽,CPU,内存的限制不能给到服务器足够的压力,这个时候你就需要用到分布式方案来解决客户机的瓶颈,压测的结果也会更加接近于真实情况. ...
- Jmeter 在linux下的分布式压测
Jmeter 在linux下的分布式压测 0.将 windows机器作为master 控制机(同时也兼做负载机slave), linux机器作为 负载机 slave. 1.linux环境安装 : (1 ...
- 分布式压测系列之Jmeter4.0第一季
1)Jmeter4.0介绍 jmeter是个纯java编写的开源压测工具,apache旗下的开源软件,一开始是设计为web测试的软件,由于发展迅猛,现在可以压测许多协议比如:http.https.so ...
- JMeter在linux上分布式压测步骤(二)
哈喽,我又来了~ 前提:三台linux虚拟机,一台作为master,另外两台作为slave. 一.server端 1.修改1099端口,client和server通信的端口,可以不修改,默认就是109 ...
- jmeter实现分布式压测步骤
环境说明:安装与控制机相同版本的jdk与jmeter 1.修改控制机中的jmeter.properties文件 将<remote_hosts=127.0.0.1>改为<remote_ ...
- Linux环境下进行分布式压测踩过的坑
背景:公司为了满足大并发的情况,需要测试组配合,就需要分布式压测,这里我把我踩过坑都记录下来: 环境:Linux + jmeter-v.5.1.1;使用3台2核4G的压力机: Q1: Server f ...
随机推荐
- nginx流量复制与放大
1. 需求 功能需求 在不影响真实业务前提下,支持: 流量复制,用于线故障分析.系统迁移评估等 流量放大,通过多倍复制,实现放大流量,用于性能压测 配置需求 支持或禁止post请求复制 记录镜像请求的 ...
- [MAUI] 混合开发概念
混合开发的概念是相对与原生开发来说的:App不直接运行原生程序,而是在原生程序中运行一个Web程序,原生程序中包含Web运行时,用于承载Web页面.暂且将原生应用称之为Web容器,Web容器应该能 ...
- puppeteer 提交 gitee - win10 (放弃,改成手点)async.series
puppeteer 提交 gitee 需求 不想每次都登录到gitee上点击发布,想自动点击. 用puppeteer 模拟下 现在是win10环境,安装比较费尽 npm i puppeteer 这里用 ...
- private priv 私人 pri=prim first v=self 自己第一
private priv 私人 pri=prim first v=self 自己第一 private v自己-私人的 pri 来自PIE*per,向前,穿过 pri = pre 向前(这么理解也说的过 ...
- AI 学习时代:大语言模型领域的行业黑话和专业术语解析
近年来,深度学习技术的快速发展带动了大语言模型在自然语言处理领域的广泛应用.在这个激动人心的领域里,我们常常会遇到一些行业黑话和专业术语.为了帮助大家更好地入门,让我们深入探讨一些关键概念,以及它们在 ...
- [C++]使用auto遍历判断是否是最后一个元素
一.背景 略 二.代码 for(auto& it:vec){ if(&it==&vec.back()){ cout<<"is the last eleme ...
- cmake:针对某些依赖 openssl-1.0 而机器上还有其他版本的 openssl
指定下列变量: -DOPENSSL_INCLUDE_DIR:指向 openssl-1.0 的 include 目录 -DOPENSSL_SSL_LIBRARIES:指向 openssl-1.0 的 l ...
- 阿里二面:谈谈ThreadLocal的内存泄漏问题?问麻了。。。。
引言 ThreadLocal在Java多线程编程中扮演着重要的角色,它提供了一种线程局部存储机制,允许每个线程拥有独立的变量副本,从而有效地避免了线程间的数据共享冲突.ThreadLocal的主要用途 ...
- C#调用HTTP POST请求上传图片
public static string UploadImage(string uploadUrl, string imgPath, string fileparameter = "file ...
- 在使用若依分离版时遇到富文本不显示html解决
<el-table-column label="公告内容" align="center" prop="content"> < ...