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 ...
随机推荐
- GoLand打开后Project消失
一直用的好好的Goland,突然不能用了,左边栏Project"消失"了. 如下: 解决方法 遇到上面问题,一般情况是GoLand的cache问题,这个时候要将GoLand清理一下 ...
- Zabbix与乐维监控对比分析(三)——对象管理篇
大家好,我是乐乐.今天就不更新zabbix6.0的使用教程了.在前面的文章中,我们详细介绍了Zabbix与乐维监控在架构.性能.Agent管理.自动发现.权限管理等方面的对比分析,本篇是Zabbix对 ...
- 基于Apollo3-Blue-MCU的智能手表方案源码解析
一 方案简介 1.简介 Apollo3 Blue Wireless SoC是一款超低功耗无线mcu芯片,它的运行功耗降至6μA/ MHz以下.该器件采用ARM Cortex M4F内核,运行频率高达9 ...
- mybatis-plus处理blob字段
转载自:www.javaman.cn 在 Spring Boot 项目中使用 MyBatis-Plus 处理 longblob 字段时,我们可以按照以下步骤进行操作.假设 longblob 存储的是字 ...
- Android 获取设备的亮度百分比
一般的屏幕亮度都是0-255,而小米手机的高版本不一样 为了使亮度调节更加细腻, MIUI对原生亮度级别进行了扩展, 由原有的255级调整根据不同屏幕分别支持255/1023/2047/4095级.开 ...
- 建筑、工程和施工产业中的3D可视化
3D视觉效果是传达想法,概念或设计的强大工具,它也用于在概念阶段推销该想法. AEC行业的可视化已经走了很长一段路,从将设计提交给客户进行批准,现在用于项目的每个阶段,从项目投标,获得客户和理事会的批 ...
- tableau 工作表分页
原创优阅达数据科技有限公司 https://mp.weixin.qq.com/s?__biz=MzA5MTU3NDI2NQ==&mid=2649465570&idx=1&sn= ...
- OREPA:阿里提出训练也很快的重参数策略,内存减半,速度加倍 | CVPR 2022
论文提出了在线重参数方法OREPA,在训练阶段就能将复杂的结构重参数为单卷积层,从而降低大量训练的耗时.为了实现这一目标,论文用线性缩放层代替了训练时的BN层,保持了优化方向的多样性和特征表达能力.从 ...
- Python连接mysql数据库和关闭数据库的方法
1 import pymysql 2 def get_conn(): 3 """ 4 :return: 连接,游标 5 """ 6 # 创建 ...
- 【已解决】ERROR: but there is no HDFS_NAMENODE_USER defined. Aborting operation. Starting datanodes
export HDFS_NAMENODE_USER=rootexport HDFS_DATANODE_USER=rootexport HDFS_SECONDARYNAMENODE_USER=roote ...