全链路仿真压测系统

news2025/1/18 6:43:55

目录

1.项目背景

2.仿真压测系统成型之路

3.  818台网实战开始

4. 总结


1.项目背景

目前常用的压测工具一般都是针对QPS这一个单一指标进行考量。即使支持编写脚本的工具也只是通过参数化模拟用户。但是实际用户是使用单独设备请求服务器,即一个用户就是一个tcp连接。

所以为了更真实的模拟用户行为,我们需要通过一个tcp连接模拟一个用户,并通过代码方式实现用户的真实请求行为。C端及中台产研中心云平台部质量保障团队自研的“仿真压测系统”。独有的QPS动态可控技术,支持固定URL压测、参数化、Websocket协议压测、中间件、数据库等的压测,模拟用户真实轨迹,通过用户侧,服务端,DB进行数据一致性和正确性自动检验,打造真正的全链路仿真压测,该系统可扩展性强,稳定性高,目前已多次支持公司级各类大型活动的仿真全链路压测,为线上服务的稳定运行提供了强有力的质量保障。

经过四年的打磨如今借此机会与大家分享一下心路历程,积极讨论,欢迎提出意见,希望可以帮助我们进一步成长。(文中引用均为测试数据)

2.仿真压测系统成型之路

2.1

工具选型

► 2.1.1 现有的压测工具对比                              

图片

图1-1

► 2.1.2  Locust发压client比较

图片

图1-2

结合以上比较结果,目前没有合适的压测工具可以直接满足我们的压测需求,最终决定用Locust做框架,首先它是一款易于使用的分布式负载测试工具,完全基于事件,单机并发能力高,并发机制是协程,其次二次开发潜力比较大。

发压的请求client采用fasthttp, 据说是目前golang性能最好的http库,原理是利用worker复用goroutine,减轻runtime调度协程的压力,相对于自带的net/http(每个连接都需要新建一个goroutine),性能有10倍的提升。省略一千字,直接上干货。

► 2.1.3 仿真压测系统特性:

  • 分布式部署;

  • 固定URL压测;

  • 参数化脚本压测;

  • Websocket协议压测;

  • 其他协议UDP、http2、 RTMP/HLS、MQTT(golang可以实现的协议都可满足)

  • Redis直压;

  • Kafka直压

  • Mysql直压;

  • 自定义脚本压测(仿真压测,全链路数据对账);

  • 动态可控QPS、TCP;

  • 秒级启动/停止,结果收集即停即展示,无需等待

……

 ► 2.1. 4 实现难点分析

模拟百万用户创建TCP/ websocket连接;长时间保持连接不断开;集中发压;

部分代码如下:

   go func() {
    for {
        select
        case data := <-r.stats.messageToRunnerChan:
            data["user_count"] = r.numClients
            r.outputOnEevent(data)
        case <-r.closeChan:
            Events.Publish("boomer:quit")
            r.stop()
            wg.Done()
            return
        }
    }
}()
集中发压
curTime := myStatus.Ct
    statusTime := myStatus.St
    c := time.After(time.Duration(statusTime-curTime) * time.Second)
    <-c
    miaosha(uidToken, &myStatus, myLog)
保持长链接
func wsWorker() {
  ws, err := websocket.Dial(wsUrl, "", origin)
  if err != nil {
  log.Println(err)
  return
  }
  defer func() {
    if p := recover(); p != nil {
    log.Println(p)
 }
 erc := ws.Close()
    if erc != nil {
     log.Println(erc)
  }
  }()
  go func() {
    ws.Write([]byte("0"))
    var t = time.Tick(time.Second * 30)
    for range t {
    if ws == nil {
        continue
    }
    ws.Write([]byte("0"))
    fmt.Println("send 0 to websocket ok!")
    }
    }()
  for {
    select {
      case <-stopChannel:
           return
      default:
        var msg = make([]byte, 512)
        start := time.Now()
        n, err := ws.Read(msg)
        log.Println(string(msg[0:n]))
        elapsed := time.Since(start)
        if myDebug {
            log.Println(string(msg))
           }
        if err != nil {
          log.Printf("Error: %s", err.Error())
        }
       }
     }
    }

2.2

日常使用截图

图片

图2-平台首页

图片

图3-实时监控压测页面,总请求数、实时qps、响应时间、发压机cpu占用等指标。

图片

图4-压测空接口,服务器监控截图, Nginx的峰值QPS可以达到596万。

图片

图5-压测redis时监控截图,单个节点的实时监控等都可以一览无余

3.  818台网实战开始

工欲善其事,必先利其器,利器已有,剧本安排上。

晚会当天数以万计的用户通过手机app参与活动,从白天开始“预约红包”,晚上八点晚会开始后用户开始陆陆续续登录app“领取预约红包”;随着主持人口播,第一轮“集卡”活动开始……人数慢慢增多,到了最激动人心的时候。“一元秒新车”开始,QPS狂飙,TCP连接数也达到了峰值100W。

开始实战:

控制台:各部门注意,入口已经放开,流量开始进入;目前“预约红包”阶段

仿真压测:收到,每五分钟递增1w用户(1TCP模拟1用户以下通用TCP数代指用户数),QPS200(用户进入活动页面,预约红包、查看规则、查看介绍等大概每人5次请求)

图片

图6-由于发压机数量32台,每个机器限制QPS7所以总QPS就是224

控制台:晚会开始,“预约红包”可领状态,“见面礼红包”已开启,“连续红包”已开启,第一场大咖讲话马上开启……

仿真压测:明白,TCP调整到20W,QPS2W(用户操作5次集中在1分钟以内)

图片

图7-动态调整QPS、TCP连接数按钮

图片

图8-设置TCP连接数、QPS、步增等

图片

图9-设置生效,TCP、QPS稳定保持在设定值

控制台:抽盲盒活动进入倒计时

仿真压测:copy,TCP调整到30W,QPS10W(用户3秒内点击10~15次提交一次请求到服务器)

图片

图10-设置生效,TCP、QPS稳定保持在设定值

控制台:时间来到最终环节,“一元秒新车”,倒计时开启

仿真压测:拼手速的时候到了,TCP100W,QPS100W(秒杀只可以提交一次)走起

图片

图11-设置生效,TCP、QPS稳定保持在设定值

至此,晚会结束,仿真压测却并没有结束,还有最后一环--“对账”。仿真压测会把接口返回用户的数据记录到kafka中,最后入库,与服务器的数据进行对账,确保每条数据的正确性。

图片

图12-服务侧数据与用户侧数据进行对账

看一下动态调整QPS的完美曲线,随着用户增长以及QPS增长的仿真图

图片

图13-仿真模拟用户递增的曲线

图片

图14-服务器监控截图,仿真用户全部走websocket协议,通过“状态机”下发指令、接收指令

图片

 图15-Redis 监控截图

图片

图16-云服务器LB截图

图片

图17-云服务器LB截图

图片

图18-云服务器LB截图

图片

图19-仿真压测完成,服务侧奖品发放明细

图片

图20-仿真侧用户领取奖品明细以及对账情况

数据完美对上。

4. 总结

由于篇幅受限,想说的很多,质量保障团队也做了很多,比如灾备演练,模拟服务器满载、域名切换、服务器宕机、机房切换等等。关于测试方面的问题欢迎私下讨论。


以下是我收集到的比较好的学习教程资源,虽然不是什么很值钱的东西,如果你刚好需要,可以评论区,留言【777】直接拿走就好了

各位想获取资料的朋友请点赞 + 评论 + 收藏,三连!

三连之后我会在评论区挨个私信发给你们~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/843445.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是重定向,怎么解决重定向问题

目录 引言 什么是重定向 为什么会发生重定向 常用的重定向方法 解决重定向问题的方法 代码示例 注意事项 总结 引言 在网络应用中&#xff0c;重定向是一种常见的技术&#xff0c;用于在浏览器请求页面时将用户重定向到另一个页面。本文将介绍重定向的概念&#xff0c…

Nginx反向代理配置+负载均衡集群部署

文章目录 负载均衡反向代理基础环境部署&#xff1a;什么是代理实验环境图流量过程 环境部署准备两台Web服务器安装Nginx准备页面内容添加主机名 代理服务器配置 修改windos hosts文件测试&#xff1a;终端浏览器 负载均衡反向代理基础环境部署&#xff1a; 什么是代理 正向代…

16-3_Qt 5.9 C++开发指南_使用QStyle 设置界面外观_实现不同系统下的界面效果的匹配

文章目录 1. QStyle的作用&#xff08;实现不同系统下的界面效果的匹配&#xff09;2. Qt内置样式的使用3. 源码3.1 可视化UI设计3.2 mainwindow.cpp 1. QStyle的作用&#xff08;实现不同系统下的界面效果的匹配&#xff09; Qt 是一个跨平台的类库&#xff0c;相同的界面组件…

D455+VINS-Fusion+surfelmapping 稠密建图(三)

继续&#xff0c;由surfelmapping建立的点云生成octomap八叉树栅格地图 一、安装OctomapServer 建图包 安装插件 sudo apt-get install ros-melodic-octomap-ros sudo apt-get install ros-melodic-octomap-msgs sudo apt-get install ros-melodic-octomap-server sudo apt-…

js-1:JavaScript中的数据类型?存储上有啥差别

1、在JavaScript中&#xff0c;共有两种数据类型。 基本类型 复杂类型 区别在于&#xff1a;存储位置不同 2、基本类型 主要分为以下6种&#xff1a; Number String Boolean Undefined null Symbol Number : 数值最常见的证书类型格式则为十进制&#xff0c;还可以设置八进制&…

K8s中的PV和PVC和监控

1.PV和PVC PV&#xff1a;持久化存储&#xff0c;对存储资源进行抽象&#xff0c;对外提供可以调用的地方&#xff08;类似&#xff1a;生产者&#xff09; PVC&#xff1a;用于调用&#xff0c;不需要关心内部实现细节&#xff08;类似&#xff1a;消费者&#xff09; 2.实…

【Gitee的使用】Gitee的简单使用,查看/创建SSH公匙、创建版本库、拉取代码、提交代码

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 本篇文章简单介绍&#xff0c;如何在Gitee上面创建版本库、拉取…

搭建企业级BI系统有多快?奥威BI表现惊人

搭建BI系统需要建立一个可靠的数据仓库和针对分析工具/UI的数据结构。同时&#xff0c;这个过程需要不断地迭代优化与维护。主要有搭建环境、建设数仓和分析模型、设计数据可视化报表。 不难看出&#xff0c;从零开始搭建企业级BI系统是一个工作量大、程序繁琐的工程&#xff…

Jenkins 使用

Jenkins 使用 文章目录 Jenkins 使用一、jenkins 任务执行二、 Jenkins 连接gitee三、Jenkins 部署静态网站 一、jenkins 任务执行 jenkins 创建 job job的名字最好是有意义的 restart_web_backend restart_web_mysql[rootjenkins ~]# ls /var/lib/jenkins/ config.xml …

AIGC+低代码:征途漫漫,道阻且长

人们总是高估一项科技所带来的短期效益&#xff0c;却又低估它的长期影响。 一、低代码与 AI 深度融合是未来发展趋势 2023 年上半年&#xff0c;随着 Chat GPT 的爆火&#xff0c;AI 在自然语言对话和代码领域的能力引发全世界的关注&#xff0c;现阶段的 AI 真的能将大家带入…

网络编程——MAC地址、IP地址和子网掩码

MAC地址、IP地址和子网掩码 一、MAC地址&#xff1a;硬件身份证 1、MAC地址的概念 MAC地址&#xff0c;即媒体访问控制地址&#xff08;Media Access Control Address&#xff09;&#xff0c;是一个用于唯一标识网络设备的物理地址。每个网络接口卡&#xff08;NIC&#xf…

I帧、P帧、B帧、GOP、IDR 和PTS, DTS之间的关系

一.视频传输原理 视频是利用人眼视觉暂留的原理&#xff0c;通过播放一系列的图片&#xff0c;使人眼产生运动的感觉。单纯传输视频画面&#xff0c;视频量非常大&#xff0c;对现有的网络和存储来说是不可接受的。为了能够使视频便于传输和存储&#xff0c;人们发现视频有大量…

用P2PNet进行大豆计数

文章目录 介绍在大豆数据集上可视化结果环境准备数据集结构数据链接模型训练模型推理代码介绍 这个仓库包含了P2PNet(Rethinking Counting and Localization in Crowds: A Purely Point-Based Framework)在大豆数据集上的pytorch实现。 在大豆数据集上可视化结果 环境准备 …

虚继承中对象占用的内存空间

1、虚继承中对象占用的内存空间1 #include <iostream> using namespace std;class AA {void show() {}int max(int a, int b) { return a > b ? a : b; } }; //函数并不占用内存空间class A {}; //占位符class B {int c; }; //含有一个int型数据成员class C :vi…

如何使用本地mock数据

当后端同事接口数据还未完成&#xff0c;我们前端开发需要使用数据时&#xff0c;怎么办呢&#xff1f;这里可以自己本地mock数据先用着啦&#xff01;仅在开发时使用 1. 创建一个 xxx.js文件&#xff0c;对外暴露一个数组&#xff1b; 对新建js文件编写导出&#xff0c;返回数…

创建线程、线程的挂起与恢复、线程的优先级与终止线程

目录 一、创建线程 CreateThread函数&#xff1a; 下面是示例&#xff1a; ​编辑 ThreadProc函数解释&#xff1a; DWORD的本质是 unsigned long PVOID的本质是 void* 二、线程的终止 1.WaitForSingleObject()函数&#xff1a; 示例如下&#xff1a; 2.ExitThread()函…

ChatGPT 作为 Python 编程助手

推荐&#xff1a;使用 NSDT场景编辑器 助你快速搭建可编辑的3D应用场景 简单的数据处理脚本 我认为一个好的起点是某种数据处理脚本。由于我打算让 ChatGPT 之后使用各种 Python 库编写一些机器学习脚本&#xff0c;这似乎是一个合理的起点。 目标 首先&#xff0c;我想尝试…

Elasticsearch同时使用should和must

问题及解决方法 must和should组合查询&#xff0c;should失效。使用must嵌套查询&#xff0c;将should组成的bool查询包含在其中一个must查询中。 SearchRequest request new SearchRequest(); request.indices("function_log");SearchSourceBuilder sourceBuilde…

第56步 深度学习图像识别:CNN梯度权重类激活映射(TensorFlow)

基于WIN10的64位系统演示 一、写在前面 类激活映射&#xff08;Class Activation Mapping&#xff0c;CAM&#xff09;和梯度权重类激活映射&#xff08;Gradient-weighted Class Activation Mapping&#xff0c;Grad-CAM&#xff09;是两种可视化深度学习模型决策过程的技术…

一文教你看懂Golang协程调度【GMP设计思想】

一文教你看懂Golang协程调度【GMP设计思想】 1 Golang调度器的由来 1.1 单进程的问题&#xff1a;进程阻塞、CPU浪费时间 单一执行程序、计算机只能一个任务一个任务来进行处理进程阻塞所带来的CPU浪费时间 1.2 多进程、多线程问题&#xff1a;设计复杂、高内存、CPU占用 设计…