写点什么

有赞全链路压测引擎的设计与实现

  • 2020-03-11
  • 本文字数:3430 字

    阅读完需:约 11 分钟

有赞全链路压测引擎的设计与实现

一年以前,有赞准备在双十一到来之前对系统进行一次性能摸底,以便提前发现并解决系统潜在性能问题,好让系统在双十一期间可以从容应对剧增的流量。工欲善其事,必先利其器,我们拿什么工具来压测呢?我们做了很多前期调研和论证,最终决定基于 Gatling 开发有赞自己的分布式全链路压测引擎 —— MAXIM。一年多来,我们使用 Maxim 对系统做了很多次的性能压测,在提升系统性能、稳定性的同时,也得益于历次压测的实践经验逐步改进 Maxim。

一、前期调研

1.1 技术选型的核心考量

由于时间或成本关系,我们打算基于开源软件做二次开发,而以下就是我们技术选型时的核心考量:


  • 将请求编排成业务场景

  • 以用户下单这个场景为例,用户完成一笔订单,可能需要打开商品主页-加入购物车-选择收货地址-下单支付这些步骤,而串起这一系列的请求就是所谓的将请求编排成业务场景

  • 流量控制

  • 流量控制可以是纵向的,如上述下单场景中,各个步骤的请求量逐渐减少,整体呈现一个漏斗模型;也可以是横向的,比如用户正在浏览 A 商品的商品详情页,然后看到了 B 商品的推荐,转而浏览 B 商品的商品详情页

  • 压力控制

  • 指压测时并发用户数、吞吐量(RPS / TPS)的控制

  • 数据跟请求参数的绑定

  • 压测往往涉及大量的测试数据,而如何绑定数据和请求参数是我们需要考量的

  • 对分布式测试的支持

  • 因为是全链路压测,自然需要多台施压机共同协作施压,自然而然的需要分布式支持

  • 测试报告

  • 良好的测试报告是我们分析性能问题的必备条件

  • 二次开发的成本

  • 由于时间或人力关系,我们也需要考虑二次开发成本

1.2 4 个主流开源性能测试框架对比

我们调研了以下 4 个主流开源性能测试框架:



  • ApacheBench

  • Apache 服务器自带,简单易用,但不支持场景编排、不支持分布式,二次开发难度较大

  • JMeter

  • JMeter 支持上述很多特性,如分布式、良好的压测报告等,但其基于 GUI 的使用方式,使得当我们的压测场景非常复杂并包含很多请求时,使用上不够灵活;此外在流量控制方面的支持也一般

  • nGrinder

  • 基于 Grinder 二次开发的开源项目,支持分布式,测试报告良好,但和 JMeter 一样,在场景编排和流量控制方面支持一般

  • Gatling

  • 支持场景编排、流量控制、压力控制,测试报告良好,且提供了强大的 DSL(领域特定语言)方便编写压测脚本,但不支持分布式,且使用 Scala 开发,有一定开发成本


以上,我们最终选择基于 Gatling 做二次开发。

二、Maxim 新增的特性

Maxim 在 Gatling 基础上开发了很多新特性:


  • 支持分布式

  • 一个控制中心(Control Center,负责调度) + 多个压力注入器(指施压机)

  • 提供 GUI,并对用户隐藏压测过程的复杂性

  • 高效地创建、运行(手动/定期)测试任务

  • 管理测试资源

  • 测试资源包括压测脚本、数据集(为压测请求提供测试数据,由数据块构成的一个集合,数据块是大量测试数据的最小分割单元)、压力注入器

  • 支持压测脚本参数化

  • Maxim 中并发用户数、RPS、持续时间等都可以通过 GUI 动态注入压测脚本

  • 支持压力注入器系统状态监控

  • 实时监控压力注入器的 CPU、内存、I/O 等指标

  • 自动生成压测报告,保留历史压测报告

  • 采集多个压力注入器的压测日志,自动汇总生成压测报告,并保留历史压测报告

三、Maxim 的技术架构

3.1 Maxim 的总体架构


Maxim 架构的主要构成:


  • Maxim Console

  • Maxim Console 主要衔接 GUI 和 Maxim Control Center,负责创建、运行测试任务,接收压力控制参数等

  • Maxim Control Center

  • Maxim 的控制中心,这里主要负责压测任务的调度、读取数据集、上传脚本和数据以及读取日志并生成压测报告

  • Load Injector Cluster

  • 压力注入器集群,主要分为 Agent 和 Gatling 两部分,Agent 负责接收 Maxim 控制中心的调度指令以及向控制中心反馈本压力注入器压测情况,而 Gatling 则是真正发起压测请求的地方,并将压测日志写入 InfluxDB

  • Data Factory

  • 压测数据首先会在大数据平台通过 MapReduce 任务生成,而数据工厂负责为控制中心读取这些数据并返回数据集

  • Cloud Storage

  • 云存储,Maxim 控制中心会将压测脚本和压测数据上传到云存储,当 Agent 收到控制中心的任务执行指令时,会从云存储下载压测脚本和对应的数据块。设计云存储的目的主要是为了模拟真实用户环境在公网发起压测请求,但有赞目前都是从内网发起压测请求,所以云存储的功能也可以以其他方式实现,比如 Agent 直接从大数据平台下载数据集

  • InfluxDB

  • 所有压力注入器产生的日志都会统一写入 InfluxDB,方便生成压测报告


Maxim 的调度算法


控制中心会根据当前测试任务使用的压力注入器数量,将数据集中的数据块平均分配给每个压力注入器,让每个压力注入器只下载对应的那些数据块。此外,并发用户数、RPS 也会被平均切分给每个压力注入器。这样,每个压力注入器的负载基本是一致的。

3.2 Maxim 的领域抽象


  • TestJob - JobExecution - JobSliceExecution

  • 当压测任务开始执行,首先会在控制中心生成 JobExecution,监控本次压测任务的整体执行状态。控制中心又会根据上述调度算法为每个压力注入器生成任务分片 JobSliceExecution 并下发到各个压力注入器,其中包含了脚本、数据集等信息

  • TestScript

  • 压测脚本

  • DataSet 和 DataChunk

  • 数据集和组成数据集的数据块单元,目前单次压测任务已支持多数据集,为多个场景提供不同的压测数据,即混合场景压测

  • LoadProfile

  • 从 GUI 接收动态参数,主要包括压力注入器数量、并发用户数、RPS、持续时间等



  • ExecPlan

  • 执行计划,包括按需执行和周期执行两种执行方式

  • ExecutionStatus

  • 关于状态机下一节会详细介绍

3.3 Maxim 的状态机


Maxim 状态机是 Maxim 分布式的核心,控制中心和各个 Agent 的行为都受状态机变化的影响。


创建任务并开始执行以后,各个任务分片(JobSliceExecution)首先会进入 preparing 状态,各个 Agent 会从云存储下载压测脚本和各自对应的那些数据块,下载完成后再将这些数据块合并成一个 Json 数据文件作为压测脚本的数据输入。如果下载失败则会重试,即 Prepare。如果所有 Agent 都成功下载了脚本和数据,则各个 JobSliceExecution 会相继进入 prepared 状态,等所有 JobSliceExecution 进入 prepared 状态后,JobExecution 也会进入 prepared 状态,并向各个 Agent 发起执行指令,各个 JobSliceExecution 进入 running 状态,等所有 Agent 执行完成且各个 JobSliceExecution 变成 completed 状态之后,JobExecution 也会进入 completed 状态,此时压测任务执行完成并生成压测报告。如果各个任务分片在 preparing、prepared 或 running 过程中有任何一个出错,则出错的分片会进入 failed 状态并通知控制中心,控制中心则控制其他分片中止正在执行的任务并进入 Stopping 状态,等这些分片中止成功并都变成 stopped 状态后,JobExecution 会被置成 failed 状态。当然了,也可以手动停止压测任务,这时候 JobSliceExecution 和 JobExecution 都会被置成 stopping->stopped 状态。

3.4 Maxim 控制中心的技术架构


Maxim 控制中心采用六边形架构(也叫端口与适配器模式),核心服务只处理核心业务逻辑(如调度算法),其他功能如与 Agent 通信、脚本存储、数据存储、压测报告等都是通过适配层调用特定实现的 API 实现。具体技术的话,与 Agent 通信使用 grpc 实现,其他功能则是通过 SPI 技术实现,我们把这一层叫做接缝层(Seam)。这样设计最大层度的解耦了核心业务逻辑和其他功能的特定实现,我们在保持接缝层 API 不变的情况下,可以自由选择技术方案实现相应的功能。比如数据服务这块强依赖了有赞的大数据平台,假设我们开源了 Maxim,外部团队就可以选择他们自己的技术方案实现数据服务,或者为了测试目的 Mock 掉。

四、改造 Gatling

原生 Gatling 是将压测日志写入本地日志文件的,而在分布式中,如果每个压力注入器都把日志写在本地,则为了基于所有日志分析生成压测报告,我们需要首先收集分散在各个压力注入器中的日志文件,这样显然是低效的。所以我们改造了 Gatling ,将所有日志都写到同一个 InfluxDB 数据库。需要生成压测报告时,控制中心从 InfluxDB 数据库读入本次压测任务的所有压测日志并保存为一个日志文件,再交由 Gatling 的日志处理模块来生成压测报告。

五、扩展 Gatling

原生 Gatling 不支持 Dubbo 压测,所以我们扩展 Gatling,实现并开源了 gatling-dubbo(点击阅读原文可达) 压测插件,具体实现方法详见 Dubbo压测插件的实现——基于Gatling

六、Maxim 的未来展望

Maxim 目前还是个单打独斗的产品,未来我们希望与大数据平台、运维平台等系统打通,让 Maxim 逐渐进化为一个一站式的压测平台,并引入更多新特性,如压测过程和压测报告的实时计算和展示等等。


2020-03-11 22:201153

评论

发布
暂无评论
发现更多内容

本地化、低时延、绿色低碳:阿里云正式启用福州数据中心

阿里云弹性计算

公有云 本地Region

论治理与创新 | 2022 开放原子全球开源峰会 OpenAnolis 分论坛圆满召开

kk-OSC

开放原子全球开源峰会

Linux操作系统下Docker的完整部署过程

Java永远的神

Docker 程序员 架构 程序人生 云原生

新闻速递 | MobTech袤博科技参与中国信通院“绿色SDK产业生态共建行动”

MobTech袤博科技

数据安全 sdk

什么样的知识付费系统功能,更有利于平台与讲师发展?

CRMEB

什么是WordPress

hum建应用专家

Wordpress 博客部署 WordPress

AI落地难?灵雀云助力企业快速应用云原生机器学习MLOps

York

人工智能 机器学习 云原生 降本增效 MLOps

【函数式编程实战】(十一) CompletableFuture、反应式编程源码解析与实战

小明Java问道之路

CompletableFuture 7月月更 签约计划第三季 反应式编程 Flow API

苹果手机iCloud钥匙串的加密缺陷

神锁离线版

apple 密码管理 密码技术 icloud keychain

JAVA编程规范之应用分层

源字节1号

软件开发 前端开发 后端开发 小程序开发

行业落地呈现新进展 | 2022 开放原子全球开源峰会 OpenAtom OpenHarmony 分论坛圆满召开

kk-OSC

开放原子全球开源峰会

18张图,直观理解神经网络、流形和拓扑

OneFlow

神经网络 深度学习

OpenAtom OpenHarmony分论坛圆满举办,生态与产业发展迈向新征程

OpenHarmony开发者

OpenHarmony

华为发布HarmonyOS 3及全场景新品,智慧体验更进一步

Geek_2d6073

定了!就在7月30日!

腾源会

开源

API 网关 APISIX 在Google Cloud T2A 和 T2D 的性能测试

API7.ai 技术团队

网关 API Gateway 谷歌云 网关性能测试

开源社区三十年 | 2022 开放原子全球开源峰会开源社区三十年专题活动圆满召开

kk-OSC

开放原子全球开源峰会

聚变云原生,赋能新里程 | 2022 开放原子全球开源峰会云原生分论坛圆满召开

kk-OSC

产学研用 共建开源人才生态 | 2022 开放原子全球开源峰会教育分论坛圆满召开

kk-OSC

开放原子全球开源峰会

分布式定时器

腾讯企点技术团队

redis 分布式 定时器

易观分析:以用户为中心提升手机银行用户体验,助力用户价值增长

易观分析

数据分析 用户体验 手机银行

Qt | 信号和槽的一些总结

YOLO.

qt 7月月更

精品方案|海泰方圆全栈式数据安全治理方案 为数据设一把“安全锁”

电子信息发烧客

不用Swagger,那我用啥?

江南一点雨

开源汇智创未来 | 2022 开放原子全球开源峰会 OpenAtom openEuler 分论坛圆满召开

kk-OSC

开放原子全球开源峰会

备战金九银十,Java研发面试题整理PDF,走到哪刷

程序知音

Java 程序员 java面试 后端技术 八股文

谈谈基于JS实现阻止别人调试通过控制台调试网站的问题

南极一块修炼千年的大冰块

7月月更

巧用ngx_lua做流量分组

转转技术团队

nginx

疫情期间佩戴口罩检测之训练检测口罩模型算法实现口罩检测步骤以及报错解决

南蓬幽

Python AI OpenCV 7月月更

数字经济时代的开源数据库创新 | 2022 开放原子全球开源峰会数据库分论坛圆满召开

kk-OSC

开放原子全球开源峰会

要想组建敏捷团队,这些方法不可少

敏捷开发

团队管理 敏捷开发 敏捷团队

有赞全链路压测引擎的设计与实现_文化 & 方法_有赞技术_InfoQ精选文章