三维家全链路压测平台实践
大家好,我是三维家架构师超凡生,本文主要阐述全链路压测在三维家的实践。本文会从背景需求、架构设计、关键技术实现等几个方面来介绍。
1. 背景
首先,我们先来了解一下什么是全链路压测?
全链路
,分为两层意思:
一是自顶向下,一个请求在系统中经过的完整路径。
二是一系列动作的集合,比如从用户登录,到浏览商品,到选择商品,到加入购物车,到支付等等这整个环节。
压测
:通过模拟海量用户对目标系统做各种操作的方式,对系统逐步施压,用于检验系统的稳定性以及吞吐量,以及早发现瓶颈点,从而更好的对系统做精确的容量规划
在互联网平台中,全链路压测的过程都是非常的繁复,一次营销活动,规范的压测过程要做的工作是很多的,包括压测前的很多准备工作,压测过程中的操作和记录,压测后的报告和环境恢复等等。需要从开始就做好流程的管理,一步一步推进,如下图所示:
在这一块如果仅仅依靠人工的管理和操作,那对于严谨性有很高要求的压测工作来说,会变得更加艰难。需要花费大量的时间来保证过程的准确性,进而保证结果的准确性。而且这种过程环节的标准依赖于人工管理,不同人使用的标准不一样,也不方便共享用例和报告,效率很低。由于标准不统一不稳定,所以测试的结果和效果也是不稳定的,如下图所示:
2. 需求
我们希望能创建一个平台,可以管理整个全链路压测的各个环节,比如比较简单的流程:
我们需要对这个过程实现平台化
和自动化
。
平台化
:测试过程规范化、可共享,同时测试用例可自由定义。
自动化
:定时进行各种测试的自动启停,全链路场景化编排,生产流量自动回放,分布式自动压测等等。
到后期,还有一个常态化
,有了基础平台的支撑,再从管理上让自动化测试和压测的工作成为日常保护系统稳定的机器人。
基于以上背景和需求,我们开始了全链路压测平台的设计和构建。
3. 整体设计
经过多次的讨论修改,我们设计了支撑全链路压测平台所需要的业务和功能模块:
全链路压测平台首先需要自动化测试
、全链路压测
、topN链路压测
、性能基线管理
、SQL压测
的基础业务支撑。
-
自动化测试
:可以在平台上配置、管理和共享接口测试的测试用例,实现零代码脚本完成接口的自动化回归测试和场景的自动化回归测试。 -
全链路压测
:可以实现在平台上进行配置、管理和共享接口、场景、全链路的分布式性能测试,同时输出保存报告和通知。 -
topN链路压测
:可以实现在生产上对 topN(流量前 N 名)的链路进行定时的自动化回放和压测。 -
性能基线
:可以通过压测结果,对性能基线进行评估和设定,以做后续的链路性能的参考基准。 -
SQL压测
:可以通过SQL直接对数据库的性能和SQL的性能进行压力测试。
基于以上的需求,我们对平台的功能模块进行划分和设计,包括:
-
测试管理
:包括自动化回归和分布式压测。这里包含链路管理、场景管理、性能测试等功能。 -
报告管理
:包括自动化回归和分布式压测的报告和通知诊断。这里包含测试报告、诊断报告、通知告警等功能。 -
流量管理
:用以支撑生产 topN 流量的压测。这里包含流量定义、录制清洗,流量回放等功能。 -
数据隔离路由
:用以支撑写接口的压测。这里包含仿真环境的管理。
4. 架构设计
平台的雏形已经逐渐清晰,大致清楚了平台大概需要哪些东西。而对于平台的架构和技术选型,我们的原则是在满足需要的情况下尽量使用相对通用的技术来实现。这对于开发者和用户会更加友好。
于是,经过多次的调整,以下是整体的技术架构设计:
平台架构主要包含这些模块:
-
流量平台
:主要负责流量的采集和清洗。需要对采集点进行部署管理。 -
管理平台
:主要负责测试流程的管理、集成和视图。 -
测试引擎
:主要负责测试请求调用的具体运行。需要多机器部署支撑。 -
报告生成
:主要负责测试结果的数据解析,生成报告视图。 -
仿真环境
:主要提供给测试过程中数据存储的环境,使压测有独立的数据环境,不影响生产。 -
mock平台
:主要对测试过程调用到第三方的接口需要做 mock 时,提供 mock 服务。 -
监控平台
:主要是在测试的过程中,对平台和测试的对象服务进行监控,记录指标,对做对比评估。
架构上整体的流程已经很清楚了,以管理平台为中心,对自动化测试、流量回放、分布式压测、数据隔离路由以及测试报告等进行定义和管理,使各个模块可以按定制需求自动运行。
确定了技术架构,我们就可以一步一步开展全链路压测平台的开发和搭建了。
5. 关键技术实现
5.1 Jmeter引擎
-
底层的测试引擎,我们选用了 Jmeter
,因为 Jmeter 功能十分强大,扩展性比较强。 -
大部分测试同学都比较熟悉,学习成本低也很容易上手,更重要的是可以通过各种控制器和接口支撑我们的自动化和分布式压测的需求。 -
当然我们也考虑过自已开发,不过因为成本较高而且 Jmeter 基本可以满足需求,同时 Jmeter 在压测也有大量的实践,所以最终也是选用了 Jmeter。
使用 Jmeter 引擎进行自动化和分布式压测的流程:
Jmx 文件是定义 Jmeter 运行各个运行组件的文件,可以被 Jmeter 识别、解析和运行。 Jtl 文件是 Jmeter 测试输出的结果数据文件,可通过对 Jtl 文件的解析,生成可视化的报告。
我们通过对 Jmx 和 Jtl 进行生成和解析,完成了平台和 Jmeter 引擎的集成。平台可以更加方便快速地定义、使用和共享 Jmeter 的功能。
5.2 生产流量回放
生产流量的特点是:数据量大、时间序列性。
所以我们在数据采集时是通过采样日志进行记录,通过时序数据库进行存储。
生产流量回放流程如下:
Csv 文件包含流量的格式化数据,可供 Jmeter 读取设置到压测请求的参数变量当中,实现多参数值压测回放。
-
我们在网关采集生产流量的数据,异步推送到 Kafka,再通过 Telegraf 流入 Influxdb。 -
然后再对流量数据进行清洗生成 Csv 文件,然后通过 Jmeter 引擎结合流量的测试场景 Jmx 文件进行分布式回放。
5.3 生产写流量压测
-
由于在生产进行有数据操作的性能测试时,会产生很多脏数据,为了避免这种情况,就需要对写压测的数据进行隔离处理。
生产写压测处理流程:
在压测平台发起压测前,统一在请求头打上压测标识。 在发起请求后,整个链路流转的过程中都会携带上这个压测标识。 在需要进行数据访问和处理时,通过压测标识,识别到压测链路。 然后修改数据访问的链路。
这里有两个问题:
如何实现在整个链路的流转中,携带压测标识?
答:我们是通过在 http 的请求头上加上压测标识,然后在整个请求的生命周期过程中,都透传这个标识,同时通过链路的上下文 reqId,串联分布式请求。
如何实现在数据访问时,识别到压测链路?
答:我们的大部分服务都是通过 Java 构建,所以目前先实现 Java 程序的路由。为了避免对服务代码产生入侵,我们使用
Java Agent
字节码技术,在 Java 启动时由外部加载,可以拦截到具体的代码类,对数据操作的类方法进行拦截,处理压测的数据请求,将其路由到仿真影子数据系统。
5.4 生产性能基线
-
在链路的压测过程中,我们常常需要接口或者场景的性能进行评估,得到性能QPS基线。 -
所以我们通过对Jmeter监听器生成的报告进行改造,增加性能基线的指标,在压测过程中,可以直观地看到压测结果与性能基线的差异,来判断接口场景的优化成果变化。
-
我们在Jmeter的Jmx文件中,增加关联的用例或者场景的关联信息,在生成的报告监听器中,根据关联的用例或者场景信息,以及产生的性能指标数据,生成性能基线数据。
以上是全链路压测平台的一些关键的技术点,当然还有比如监控平台,mock 平台这些也很重要,特别是监控平台,是压测过程中很重要的一环。不过监控不单单只属于全链路压测的范畴,涉及内容也很多,这里就不再介绍了。
6. 总结
本文我们讨论了全链路压测平台在三维家是如何一步一步地构建起来的,从整体上介绍了技术架构,也介绍了一些关键技术的实现方案。
由于篇幅有限,有些细节没办法全部展现,后续会持续发布更新一些平台实现的细节。感觉兴趣的同学欢迎持续关注。