全链路压测在大搜车的探索与实践

如果把双 11 定义为电商公司一年一度的大考,那么全链路压测就是大考之前的一次次模拟考试,帮助要上战场的系统查缺补漏以及进行容量验证和规划。

背景

微服务拆分的背景下,一个简单地请求可能涉及到十几个下游服务,从 CDN 到接入层、前端应用、后端服务、缓存、存储、中间件,哪怕一个环节出现一点误差,误差在上下游经过几层累积后会造成什么影响谁都无法确定,也许是调用延迟,也许是请求失败,用户的体验自然就无法保证。

所以我们需要建立起一套验证机制,来验证我们各个环节的都是符合我们预期的。验证的最佳方法就是让事件提前发生,如果我们的系统能够提前经历几次“双 11”,容量的不确定性问题也就解决了。全链路压测的诞生解决了容量的确定性问题!

核心要素

  • 采集线上的真实流量作为压测数据

  • 省去巨大的人工成本:传统压测模式下,压测数据的准备一直是老大难的问题。双 11 可能涉及几十个系统,每个系统都有几十上百的接口。如果所有接口都要压测,准备数据需要巨大的人工成本。如果只压测核心接口,其它接口的隐患可能就无法发现。
  • 解决数据多样性不足:准备的压测数据往往跟线上真实的流量模型存在差异,很可能会过多的命中 cache 或者数据库缓存。
  • 数据转换:敏感数据脱敏,不符合的数据改造
  • 直接在线上的真实环境进行双 11 模拟

  • 新搭建可对比线上环境的压测环境,成本太大;
  • 测试环境或预发环境压测结果没有说服力,参考价值不大
  • 识别压测流量和真实流量,不产生脏数据,并且不需要业务方改造适配(涉及的系统多且风险较大)

  • 压测流量打上标识,通过 trace(链路追踪中间件)向下游系统传递。
  • 压测流量触发的数据库操作都路由到影子库,不对线上数据库产生影响
  • 第三方系统的 mock
    • 有些第三方系统按照调用次数收费
  • 监控
    • 系统 qps, 耗时
    • 硬件监控(cpu, 内存)等

系统架构

如下图所示,全链路压测分为基础设施和管理端两大部分。

基础设施

基础设施采用了 Java 动态字节码技术,运行在 jvm 层,已经覆盖了公司 90% 以上的应用。

TraceAgent 负责记录链路调用,打印日志到磁盘上。每台机器上都部署了我们的链路日志收集程序,然后把它们存储到 ES 等后端存储中。 全链路压测的数据就是通过这些日志转换而成,同时,基于日志的聚合分析,也形成了我们的监控大盘。

PTS-Agent 主要负责影子库,mock 等逻辑实现。所有的压测流量都打上了压测标识,而且通过 trace 传递,即使跨系统调用压测标识也不会丢失。PTS-Agent 在发现是压测流量,并且配置了影子库,就会动态修改数据库连接,把它们路由到影子库,而正常流量不会受到任何影响,真正实现了业务无感知。mock 等功能也是判断是否是压测流量,是否配置了 mock,执行流程如下图:

管理端

压测执行流程主要分为三步: 准备压测数据 ===> 配置压测计划 ===> 执行压测任务

管理端模块也是按照上面三个步骤划分的

  • 数据集管理:我们提供了灵活的 sql,可以让用户自由的选择采集,哪些应用,哪些接口,多长时间段的线上数据。
  • 压测计划管理:为每个压测场景 配置 影子库,接口 mock 等
  • 压测执行:配置施压机,线程数等,以及开始和停止压测任务实践案例
  1. 数据采集:指定时间范围 以及通过 sql 语法指定采集的应用以及接口

2. 配置压测计划

接口 mock 配置:我们基于链路数据,把需要压测的所有接口的下游调用链路都分析出来,用户可以根据我们的链路图,对任何下游接口实现 mock。

影子库、mq 配置:

数据转换功能:如果采集到的谁要做进一步的处理才能使用,则使用数据转换功能,支持 js 语法;

3. 压测执行

3.1 任务的启动与停止,线程数配置

3.2 执行过程的监控,包括 QPS、响应时间、相应状态码、cpu 和内存资源情况,

系统瓶颈定位工具

压测只是手段,我们的目的还是希望发现系统中的瓶颈点。为此,我们也提供了 应用拓扑链路追踪 协助大家排查问题,同时也推荐开源工具 async-profiler 分析方法耗时情况。

应用拓扑:全局视角,快速定位下游系统瓶颈点

该系统可以展示当前系统所有的下游系统,在哪个节点耗时最长一目了然

链路追踪:记录所有调用,方便分析所有慢请求

未来规划

未来,我们会朝着高可用平台发展,不仅会满足大家压测种种需求,同时也将为 故障模拟,故障演练等场景赋能,帮助大家提供故障应对能力,敬请期待。