locust压测框架实战案例2 locust压测websocket
suiw9 2024-10-26 14:29 28 浏览 0 评论
一、接上回的内容:https://m.toutiao.com/is/RQbHxWg/
本次要实现的是新增自定义的图表到locust的report.html中;
二、准备工作
1. 先下载代码:https://github.com/locustio/locust 检出release分支,这次用的是2.4.3;
2. 之前没怎么看过生成报告相关的代码,这次看完之后基本了解得差不多,如果要自行阅读,推荐一个顺序:stats.py->web.py->static/locust.js->templates/stats_data.html->templates/report.html,locust的web服务用的是flask,报表生成用的echarts,中间还用到了jinja2;
3. 整理一下流程
a) env初始化了stats对象,create_runner的时候注册request回调将数据提交到stats对象,压测过程中的request.fire会触发回调将数据提交(比如response.success()),网页端每2秒会从webserver请求一次stats的数据,然后调用update_stats_charts函数生成Charts页面的图表;
b) Download Data下的Download Report按钮在上述流程中用到了jinja2来生成静态html,模板位于templates的report.html和stats_data.html,注意js使用的几个变量是在stats_data.html页面用jinja2语法申明和初始化的,自定义的变量也要追加到这个模板文件里;
4. 业务需求,1) 要在locust web网页的Charts下面新增目标业务耗时打点统计的堆叠图,数据源是每次业务请求响应内容里的一个字典,包含了5个k-v,分别记录了一次业务执行过程中5个阶段的耗时;2) locust Download Report按钮生成的report.html中新增耗时统计的堆叠图;
三、大致实现
a) 先说几个遇到的需要注意的点
i. 下载代码后还要安装依赖进行测试和编译pip install wheel setuptools tox,编译命令看Makefile;编译完成之后把build/lib/locust文件夹复制到项目工程的根目录进行调试;
ii. response触发fire回调是在self.__exit__()内部做的,success()只是标记一下状态,所以不要再with ... as response:的函数体内部使用self.environment.events.request.fire(),这样会导致重复统计;
iii. 需要多了解下echarts的内容,改图表才能更效率;jinja2的语法有些行如果有换行会报错;vscode对js文件的自动格式化,也会导致运行报错;
b) 因为涉及到部分公司业务,所以只列出需要改动的地方;
1. runners.py
class Runner:
def __init__(self, environment):
def on_request_success(request_type, name, response_time, response_length, **_kwargs):
self.stats.log_request(request_type, name, response_time, response_length, **_kwargs)
2. 压测脚本的task
with self.client.post(self.url, json=data, headers=headers, catch_response=True) as response:
if response.status_code == 200:
response.request_meta.update({"metrics": response.json()["data"]["metrics"]})
response.success()
3. stats.py
class RequestStats:
def log_request(self, method, name, response_time, content_length, **kwargs):
metrics = kwargs.get("metrics")
self.total.log(response_time, content_length, metrics)
self.get(name, method).log(response_time, content_length, metrics)
class StatsEntry:
metrics = None
metrics_cache = None
def log(self, response_time, content_length, metrics):
...
if metrics:
self.cache_metrics(metrics)
def extend(self, other):
…
self.cache_metrics(other.metrics)
def serialize(self):
return {
…
"metrics": self.metrics
}
def unserialize(cls, data):
...
for key in […, "metrics"]:
…
...
def cache_metrics(self, ms):
if not ms:
return
if not self.metrics:
self.metrics = {}
for x in ms:
self.metrics[x] += ms[x]
def get_metrics(self):
if not self.metrics:
return {}
count = self.metrics.get("count")
if count == 0:
if self.metrics_cache:
return self.metrics_cache
return self.metrics
tmp = {}
for x in self.metrics:
tmp[x] = int(self.metrics[x] / self.metrics["count"])
self.metrics_cache = tmp
self.metrics = {}
return tmp
def stats_history(runner):
while True:
...
if runner.state != "stopped":
metrics = stats.total.get_metrics()
r = {
...
"cost": metrics.get("cost") or 0
}
...
4.web.py
class WebUI:
def __init__(...):
def request_stats():
...
metrics = environment.runner.stats.total.get_metrics()
report.update(metrics)
return jsonify(report)
5.static/locust.js
function update_stats_charts() {
if (stats_history["time"].length > 0) {
renderCostChart.chart.setOption({
xAxis: { data: stats_history["time"] },
series: [
{ data: stats_history["cost"], markLine: createMarkLine(), stack: 'Total', emphasis: { focus: 'series' }, areaStyle: {} },
]
});
}
}
...
var CostChart = new LocustLineChart($(".charts-container"), "Cost Times (ms)", ["cost"], "ms");
...
charts.push(rpsChart, responseTimeChart, CostChart, usersChart);
...
function updateStats() {
$.get('./stats/requests', function (report) {
try {
...
stats_history["cost"].push({ "value": report.cost, "users": report.user_count });
update_stats_charts();
...
6.templates/stats-data.html
{% set cost_data = [] %}
{% for r in history}...{% do cost_data.append({"value": r.cost, "users": r.user_count}) %}...var stats_history = {..."cost": {{ cost_data | tojson }}...};
7.templates/report.html
<script>
{% include 'stats_data.html' %}
var CostChart = new LocustLineChart($(".charts-container"), "Cost Times (ms)", ["cost"], "ms");
...
if(stats_history["time"].length > 0){
CostChart.chart.setOption({
xAxis: {data: stats_history["time"]},
series: [
{data: stats_history["cost"], stack: 'Total', emphasis: { focus: 'series' }, areaStyle: {}},
]
});
...
来看看最终效果:
相关推荐
- 俄罗斯的 HTTPS 也要被废了?(俄罗斯网站关闭)
-
发布该推文的ScottHelme是一名黑客,SecurityHeaders和ReportUri的创始人、Pluralsight作者、BBC常驻黑客。他表示,CAs现在似乎正在停止为俄罗斯域名颁发...
- 如何强制所有流量使用 HTTPS一网上用户
-
如何强制所有流量使用HTTPS一网上用户使用.htaccess强制流量到https的最常见方法可能是使用.htaccess重定向请求。.htaccess是一个简单的文本文件,简称为“.h...
- https和http的区别(https和http有何区别)
-
“HTTPS和HTTP都是数据传输的应用层协议,区别在于HTTPS比HTTP安全”。区别在哪里,我们接着往下看:...
- 快码住!带你十分钟搞懂HTTP与HTTPS协议及请求的区别
-
什么是协议?网络协议是计算机之间为了实现网络通信从而达成的一种“约定”或“规则”,正是因为这个“规则”的存在,不同厂商的生产设备、及不同操作系统组成的计算机之间,才可以实现通信。简单来说,计算机与网络...
- 简述HTTPS工作原理(简述https原理,以及与http的区别)
-
https是在http协议的基础上加了一层SSL(由网景公司开发),加密由ssl实现,它的目的是为用户提供对网站服务器的身份认证(需要CA),以至于保护交换数据的隐私和完整性,原理如图示。1、客户端发...
- 21、HTTPS 有几次握手和挥手?HTTPS 的原理什么是(高薪 常问)
-
HTTPS是3次握手和4次挥手,和HTTP是一样的。HTTPS的原理...
- 一次安全可靠的通信——HTTPS原理
-
为什么HTTPS协议就比HTTP安全呢?一次安全可靠的通信应该包含什么东西呢,这篇文章我会尝试讲清楚这些细节。Alice与Bob的通信...
- 为什么有的网站没有使用https(为什么有的网站点不开)
-
有的网站没有使用HTTPS的原因可能涉及多个方面,以下是.com、.top域名的一些见解:服务器性能限制:HTTPS使用公钥加密和私钥解密技术,这要求服务器具备足够的计算能力来处理加解密操作。如果服务...
- HTTPS是什么?加密原理和证书。SSL/TLS握手过程
-
秘钥的产生过程非对称加密...
- 图解HTTPS「转」(图解http 完整版 彩色版 pdf)
-
我们都知道HTTPS能够加密信息,以免敏感信息被第三方获取。所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议。...
- HTTP 和 HTTPS 有何不同?一文带你全面了解
-
随着互联网时代的高速发展,Web服务器和客户端之间的安全通信需求也越来越高。HTTP和HTTPS是两种广泛使用的Web通信协议。本文将介绍HTTP和HTTPS的区别,并探讨为什么HTTPS已成为We...
- HTTP与HTTPS的区别,详细介绍(http与https有什么区别)
-
HTTP与HTTPS介绍超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的...
- 一文让你轻松掌握 HTTPS(https详解)
-
一文让你轻松掌握HTTPS原文作者:UC国际研发泽原写在最前:欢迎你来到“UC国际技术”公众号,我们将为大家提供与客户端、服务端、算法、测试、数据、前端等相关的高质量技术文章,不限于原创与翻译。...
- 如何在Spring Boot应用程序上启用HTTPS?
-
HTTPS是HTTP的安全版本,旨在提供传输层安全性(TLS)[安全套接字层(SSL)的后继产品],这是地址栏中的挂锁图标,用于在Web服务器和浏览器之间建立加密连接。HTTPS加密每个数据包以安全方...
- 一文彻底搞明白Http以及Https(http0)
-
早期以信息发布为主的Web1.0时代,HTTP已可以满足绝大部分需要。证书费用、服务器的计算资源都比较昂贵,作为HTTP安全扩展的HTTPS,通常只应用在登录、交易等少数环境中。但随着越来越多的重要...
你 发表评论:
欢迎- 一周热门
-
-
Linux:Ubuntu22.04上安装python3.11,简单易上手
-
宝马阿布达比分公司推出独特M4升级套件,整套升级约在20万
-
MATLAB中图片保存的五种方法(一)(matlab中保存图片命令)
-
别再傻傻搞不清楚Workstation Player和Workstation Pro的区别了
-
Linux上使用tinyproxy快速搭建HTTP/HTTPS代理器
-
如何提取、修改、强刷A卡bios a卡刷bios工具
-
Element Plus 的 Dialog 组件实现点击遮罩层不关闭对话框
-
日本组合“岚”将于2020年12月31日停止团体活动
-
SpringCloud OpenFeign 使用 okhttp 发送 HTTP 请求与 HTTP/2 探索
-
tinymce 号称富文本编辑器世界第一,大家同意么?
-
- 最近发表
- 标签列表
-
- dialog.js (57)
- importnew (44)
- windows93网页版 (44)
- yii2框架的优缺点 (45)
- tinyeditor (45)
- qt5.5 (60)
- windowsserver2016镜像下载 (52)
- okhttputils (51)
- android-gif-drawable (53)
- 时间轴插件 (56)
- docker systemd (65)
- slider.js (47)
- android webview缓存 (46)
- pagination.js (59)
- loadjs (62)
- openssl1.0.2 (48)
- velocity模板引擎 (48)
- pcre library (47)
- zabbix微信报警脚本 (63)
- jnetpcap (49)
- pdfrenderer (43)
- fastutil (48)
- uinavigationcontroller (53)
- bitbucket.org (44)
- python websocket-client (47)