百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

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,通常只应用在登录、交易等少数环境中。但随着越来越多的重要...

取消回复欢迎 发表评论: