全链路压测思路

一、时机

首先要清楚的一点就是,什么时候开始做全链路压测?我们有另外一个业务线,现在就没有打算做,那个业务线的日均单不到十万,而要压测的业务线的日均单到了200万,但这并不意味着200万是一个标准,我觉得可以从下面几点考虑:

  • 业务发展速度。在可以预期的一段时间(最好是半年,一个季度有点晚)内,业务会有较快速的发展,线上机器必须要大幅度扩容;但是,扩容有的时候并不是线性的,从两台扩展到四台,你得服务能力或者能提高两倍,但是在继续扩容,服务能力就有可能提高不上去了,因为要受限于其他的模块,比如,DB,公共组建,中间件等等。
  • 链路的复杂程度在扩张。一般而言,随着业务的发展,我们的接口会越来越多,系统会逐渐的做分布式,业务线内部的模块越抽象越多,业务线跟其他业务线的交互也也越来越多,我们无法单纯的根据自己系统的处理能力来评估接口的服务能力。
  • 对单机压测结果越来越没有自信。这也是一个很好的指标,一般而言,我们都会压一下我们自己的模块,但是身为模块的owner,自己越来越清楚,单机的压测不代表真实的场景,内心会越来越虚,这个时候,就要考虑全链路了。

二、方法

下面具体看看要做全链路需要哪些工作。

1、梳理核心链路的流程和边界

因为全链路一定会设计多个流程,多种技术,多个依赖,所以,要做全链路压测,首先要梳理核心链路的流程,明确链路的边界,我觉得梳理这个是比较简单的,因为一个业务再复杂,它的核心链路肯定有限,例如,我们的核心链路就包括:

  • 创建订单
  • 开始形成
  • 获取行程费用
  • 结束订单
  • 支付订单
  • 完单

核心链路是一个业务的核心,这一块应该可以很快梳理清楚,但是,难点在于梳理清楚链路的边界。例如:

  • 开始订单要做风控
  • 结束订单要发券
  • 结束订单要通知用户费用
  • 完单后要通知营销
  • 。。。

在核心链路的基础上,我们会有很多的分支业务,而这些分支业务有的可以参与压测,有的不能参与压测:原因多种多样,比如,这个分支业务不是我们自己公司的,或者这个分支业务本身就不怎么重要,可以降级掉,甚至有的业务就是不能压测,比如给用户下放push消息。

在具体实施的时候,业务反复跟整个链路的每个业务owner反复确认,哪些是核心业务,哪些是分支业务,哪些参与压测,哪些不参与压测,把这些形成文档,逐个跟进。

2、提供全链路压测的底层支持

要做全链路,要实现非核心链路的降级,就必须对底层的产品,例如中间件,数据库访问,MQ等做改动,让这些中间件支持全链路压测。我们整体看看,一般需要哪些改动。

我们把模型简化一下,如下图,虽然是简化的,但是基本上包括主流的分布式业务的技术栈。

可以看到,底层主要需要提供下面的支持:

  • 全链路透传压测标志:必须有一种在全链路透传压测标志的能力,并且必须基于一次请求,也就是同一个traceId,现在,大部分分布式业务都会接入trace系统,例如,google的dapper,阿里的鹰眼等,对trace系统进行改造,使其能够透传压测标志,需要透传的路径大概有:HTTP、RPC(DUBBO)、MQ、线程池等。
  • 影子表:参与压测的业务,要逐个排查自己依赖的数据库,然后创建影子表,影子表必须跟正常表的schema保持一致,可以在每次压测时候手动创建,也可以推动DBA自动创建。创建好影子表后,如果当前流量是压测流量,那么写入和读取都走影子表。如果有自己的数据库中间件最好,没有的话可以借助于Mybatis的Interceptor机制。
  • 日志-影子目录:为了防止压测流程的日志对正常日志造成干扰,需要改造日志组件,将压测流量产生的日志落入到影子目录。影子目录可以有日志组件自动创建。
  • MQ支持是否消费压测流量:有的时候,全链路会通过MQ进行传递,所以,必须在消费MQ的时候进行选择:是否选择消费压测流量的MQ消息。这就需要对MQ系统进行改造,一方面使其可以透传压测流量,另一方面,需要支持配置是否消费压测的MQ消息。
  • 缓存,大数据隔离:还有一些场景,比如,缓存层,大数据层对压测流量的处理也要考虑隔离。缓存可以使用不同的集群;大数据可以直接不收集压测的数据。

3、思考全链路压测的数据怎么mock

流程支持之后,还有关键的一步,就是考虑如何构造压测的mock数据。在使用影子表之后,可以比较轻松的实现跟正常数据隔离,那剩下的就是好构造好mock数据,有几点需要考虑:

  • 用户数据要提前做好认证等准备工作。
  • Mock数据要尽可能跟真实数据保持一致,比如,价格水平,图片数量,地址信息等等。
  • Mock数据有些限制需要放开,比如,库存,一些运营性质的活动可以取消等。
  • 千万不要污染正常数据:认真梳理数据处理的每一个环节,确保mock数据的处理结果不会写入到正常库里面。

4、做好压测流量的降级预案

这一点尤其重要,特别当业务特别的复杂的时候,一定要确认好,第三方依赖能不能接收压测流量,所以,只要依赖第三方的服务,我们都要接入压测流量降级的开关,防止对第三方服务的污染。实现上,可以集成到RPC机制上,也可以提供类似于单独的限流组件。

5、梳理监控体系

确认好流程的技术支持和Mock数据的支持后,还要让每个业务梳理自己的监控,确保压测时候能够准确,及时的发现问题。

  • 核心接口和核心依赖的流量和耗时监控。
  • 中间件组件,缓存,数据库的监控报警。
  • 机器的指标报警。

6、线下做好预演

真实的压测之前,肯定要进行预演,预演主要确认:

  • 压测流程是否写入到了正确的目的地,例如,写入到影子表,影子目录,压测cache等等。
  • 压测流量的降级是否完备和有效。
  • 进一步确保监控都已到位。

7、尽量模拟现实

我们压测的脚步要尽可能的模拟现实,比如:

  • 购买的行为:不是下单后立即购买,而是要等一下子。
  • 骑车子的行为:开锁后并不是里面换车,而是骑一会。
  • 用户付款的行为:压测时候肯定不会真的让用户付款,所以我们得模拟用户付款。
  • 购买商品的数据。
  • ...

压测的脚本要跟各个业务确认,尽量跟线上真实的用户行为保持一致。

8、逐步平滑加压

压测的时候,逐步加压,并且要保持平滑加压,不要把一秒的流量都在前面几毫秒内都压出去。

9、形成报告

每次压测后进行复盘,总结压测中的问题,压测结果,机器的指标等数据形成报告发给大家,制订好后续的Action以及跟进的负责人。

三、推进

全链路压测的技术难点不多,除了要花时间梳理流程和思考如何处理数据之外,最难的就是整个链路跨多个业务,甚至部门,需要跟进每个业务线的进度,确保大家能够在给定的时间点进行联调以及进行压测。在推进的时候,按照核心链路所在的模块进行跟进,每个模块出一个owner,各个owner跟进核心的接口和依赖,每周大家碰一下同步下总体的进度。

posted @ 2021-11-18 17:56  安琪儿一直在  阅读(269)  评论(0编辑  收藏  举报