写点什么

美团全链路压测自动化实践

2019 年 4 月 04 日

美团全链路压测自动化实践

境内度假是一个低频、与节假日典型相关的业务,流量在节假日较平日会上涨五到十几倍,会给生产系统带来非常大的风险。因此,在 2018 年春节前,基于美团基础的压测平台 Quake,我们把整个境内度假业务接入了全链路压测,来系统性地评估容量和发现隐患,最终确保了春节期间系统的稳定。


在整个过程中,我们意识到,全链路压测在整个系统稳定性建设中占有核心重要的位置,也是最有效的方案。结合实际业务节假日的频率(基本平均一个月一次),如果能够把它作为稳定性保障的常规手段,我们的系统质量也能够得到很好的保障。同时,为了解决周期常态化压测过程中人力成本高、多个团队重复工作、压测安全不可控,风险高等痛点,我们提出了全链路压测自动化的设想。


通过对压测实施的具体动作做统一的梳理,在压测各个阶段推进标准化和自动化,尽力提升全流程的执行效率,最终达到常态化的目标,如图 1 所示:



图 1 自动化落地整体思路


另外,在全链路压测的整个周期中,压测安全和压测有效性也是需要一直关注的质量属性。基于这些思考,如图 2 所示,我们把压测自动化需要解决的关键问题进行了归类和分解:


  • 基础流程如何自动化,提高人效;

  • 如何自动做好压测验证,保障压测安全;

  • 压测置信度量化如何计算,保证压测有效。



图 2 问题分析


最终,基于美团基础的压测平台 Quake(在整个系统,主要提供流量录制、回放、施压的功能),设计并实现了全链路自动化压测系统,为不同业务实施全链路压测提效,并确保压测安全。该系统:


  • 提供链路梳理工具,能够自动构建压测入口链路完整的依赖信息,辅助链路梳理;

  • 支持链路标注和配置功能,对于无需压测触达的依赖接口,可以通过配置化手段,完成相关接口的 Mock 配置,不用在业务代码中嵌入压测判断逻辑;

  • 提供抽象的数据构造接口,通过平台,用户可以配置任意的数据构造逻辑和流程;

  • 在压测前/压测中,自动对压测服务和流量做多项校验,保障压测安全性;

  • 在平日,基于压测计划提供周期性小流量的压测校验,使得业务迭代变更带来的压测安全风险被尽早发现;

  • 提供压测计划管理功能,通过系统自动调度和控制施压过程,解放人力;同时强制前置预压测,也提高了安全性;

  • 一键压测,自动生成报告,收集链路入口和告警信息,提供问题记录和跟进功能。


系统设计

系统总体设计


图 3 系统总体逻辑架构


系统的总体逻辑架构,如图 3 所示,主要包括链路构建/比对、事件/指标收集、链路治理、压测配置管理、压测验证检查、数据构造、压测计划管理、报告输出等功能模块。通过这些模块,为全链路压测的整个流程提供支持,尽力降低业务部门使用全链路压测的门槛和成本。


链路构建/比对:负责服务接口方法调用链路的构建、更新、存储。


链路治理:基于构建的链路关系,提供链路中核心依赖、出口 Mock 接口等标注、上下游分析、展示,以及出口 Mock 的配置等功能。


压测配置管理:自动发现注册服务的 Mafka(美团基于 Kafka 开发的一个分布式消息中间件综合解决方案)/Cellar(基于 Tair 开发的分布式 KV 存储服务)/Squirrel(基于 Redis-Cluster 模式进行二次开发的分布式缓存系统)/Zebra(美团数据库访问层中间件)的压测配置,辅助压测方核查和配置相关配置项。


压测验证检查:确保系统可压测,通过多种校验手段和机制设计,来保证压测的安全性。


数据构造:为不同业务压测实施准备基础和流量数据。


压测计划管理:设定压测执行计划,并依赖“压测控制”模块,自动调度整个压测执行过程。


故障诊断:依据收集的关键业务/服务指标、报警等信息,判断分析服务是否异常,以及是否终止压测。


置信度评估:从数据覆盖、链路覆盖、技术指标等维度评估压测结果的置信度,即与真实流量情况下各评估维度的相似性。


非功能性需求说明:


可扩展性


  • 能够兼容不同业务线数据构造逻辑的差异性。

  • 能够支持不同的流量录制方式。


安全性


  • 集成 SSO,按用户所属团队分组,展示所属的压测服务信息。对关键操作留存操作日志。

  • 压测验证检查,是确保压测安全的关键。支持周期性压测验证,能发现待压测服务可压测性随时间的退化。


可重用性


长远看,链路构建、事件/指标收集/故障诊断等模块,在稳定性领域是可重用的基础设施,按独立通用模块建设。


约束说明:


基于 Quake 搭建,流量的录制、回放、施压等依赖 Quake。


以下对部分关键模块设计做详细介绍。


链路治理模块设计


图 4 链路治理示意图


链路治理模块是基于链路构建模块实现的。链路构建模块,底层是以闭包表的方式存储两个维度(服务和接口)的链路关系的,会周期自动地构建或更新。


链路治理模块主要提供链路入口选取、链路标注、服务出口分析、出口 Mock 配置等功能。如图 4 所示,注册压测的服务构成了压测服务的范围,也就确定了各个链路的边界。通过系统自动构建的树结构方式的链路关系,可以辅助压测方对整个链路的梳理,它解决了以往链路梳理靠翻代码等低效手段,缺少全链路视角无法做到完备梳理等问题。



图 5 出口 Mock 配置化


同时,针对整个压测范围,依赖接口可以做人工标注。哪些需要 Mock,哪些不需要 Mock,如此压测特有的链路信息能够得到持续的维护。


对于需要 Mock 的外部接口(如图 4 中的接口 C),待压测系统通过引入专有 SDK 的方式,获得出口配置化 Mock 的能力。如图 5 所示,这里使用了美团酒旅 Mock 平台的基础能力,采用 JVM-Sandbox 作为 AOP 工具,对配置的需要 Mock 的外部接口做动态能力增强。在接口调用时,判断是否是压测流量,是的话走 Mock 逻辑,做模拟时延处理,返回提前配置的响应数据。这样的话,第一,简化了出口 Mock 的操作,业务代码里 Mock 逻辑 0 侵入;第二,把之前本地 Mock 与借助 Mockserver 的两种解决方案用一种方案替代,便于统一管理;第三,在实际压测时,平台还可以通过 SDK 收集 Mock 逻辑执行的数据,自动与后台标注的 Mock 数据对比,来确保应该被 Mock 的出口确实被 Mock 掉。


数据构造模块设计


图 6 数据构造


数据构造模块是为了解决不同业务对于基础数据和流量数据的差异化构造流程。提出了两个关键的概念:数据构造逻辑和数据构造流程。数据构造逻辑,是数据构造的细粒度可复用的基本单元,由一段 Java 代码表示。平台提供统一抽象的数据构造接口,基于 Java 动态编译技术,开发了一个 Java 版的脚本引擎,支持构造逻辑的在线编辑与更新。同时,基于美团 RPC 中间件泛化调用能力,构建了泛化调用工具,帮助用户把外部基础数据构造接口的调用集成到一个数据构造逻辑中。


数据构造流程,定义了压测基础数据和流量数据生成的整个流程。通过与 Quake 的交互,获取原始真实的线上数据;构建了一个简版的流程引擎,在统一设定的流程中,如图 6 所示,通过在标准扩展槽中,配置不同类型的数据构造逻辑和执行顺序,来定义整个数据构造执行的流程;最后,把构造的流量数据与 Quake 压测场景绑定,作为后续 Quake 压测施压中,场景回放流量的来源。


通过这样的设计,能够支持任意数据构造逻辑,通用灵活。同时集成了 Quake 已有的流量录制功能,一键执行数据构造流程,大大地提升了效率。


压测验证模块设计


图 7 美团服务压测验证示意


对于压测安全性的保障,一直是自动化的难点。之前的经验多是在非生产环境压测或预压测过程中,依靠不同服务相关负责人的人工确认。这里针对压测验证,提供两条新的思考角度:一个是从待压测服务系统可压测性的角度看;一个是从压测流量特征的角度看。对于第一个角度,一个服务支持压测需要满足压测数据和流量的隔离。对于不同的系统生态,需要满足的点是不同的,对于美团生态下的服务,可压测的条件包括组件版本支持压测、影子存储配置符合预期等等。


从这些条件出发,就可以得到下面这些静态的校验项:


  • 服务依赖中间件版本要求校验;

  • Zebra 压测配置校验;

  • Cellar/Squirrel 压测配置校验;

  • Mafka 压测开关同步及校验;

  • 服务 Mock 逻辑存在性校验。


而从第二个角度来看,就是关注压测流量下会产生哪些特有的流量特征数据,通过这些特有的数据来确保压测的安全性。这里主要有三类数据:美团分布式追踪系统(MTrace)中调用链路的压测标记数据(正常的压测链路应该是一直带有压测标记,直到压测范围的边界节点,可参考图 4);标记 Mock 的外部接口被调用时,上报的运行数据;基于监控系统得到的压测流量特有的监控数据。利用这些数据,我们设计了三种动态的校验项,发现压测标记丢失、Mock 出口被调用等异常情况:


MTrace 链路标记校验,从压测链路入口出发,收集压测链路信息,校验压测标记信息传递是否符合预期。



图 8 MTrace 链路标记校验示意


服务 Mock 逻辑压测标记校验,通过增强的校验逻辑,把执行信息上报到平台,与 Mock 配置时的标注数据对比验证。



图 9 服务 Mock 压测校验示意


压测与真实链路比对校验,利用链路治理模块构建链路的能力,采集压测监控数据重构链路,与真实链路对比验证。



图 10 压测与真实链路对比示意


除了明确静态和动态两类压测校验规则,在具体流程安排上,在压测时和平日两个时期执行这些规则。既能把压测校验的压力分散到平时,也能尽快地发现服务因代码迭代引入的新风险。


在压测时,通过强制前置预压测的流程设计以及静态/动态压测校验项的自动执行,保障安全这个事情。校验不通过,给出告警,甚至在允许的情况下直接终止设定的压测计划。


在平日,通过执行周期性小流量压测校验,在施压过程中对 QPS 做个位数的精细控制,以尽量小的代价快速发现压测范围内压测安全性的退化。


压测计划管理模块设计

压测计划管理模块,提供压测计划的提前设定,然后模块能够自动调度和控制整个施压过程。如图 11 所示,这里的压测计划是多个压测场景的组合,包含 QPS 的增长计划等信息,主要分为预压测和正式压测两个阶段。压测计划的自动实施,能够解决尤其多场景组合压测,操作耗时多、多场景压测 QPS 无法同步变更、压测方无法兼顾操作和观测等问题,提升了效率。同时,在压测计划执行状态机里,预压测正常执行完成,状态才能迁移到正式压测的开始状态,提高了压测安全性。



图 11 压测计划执行


从图 11 可以看到,压测计划模块,是整个自动化压测的核心,协同起了各个模块。通过具体的计划任务执行产生的事件,触发了压测验证检查、压测进展播报、收集压测监控/告警等数据,来检测服务是否异常,并根据配置来终止压测,能够故障时及时止损。最后,报告生成模块收到压测终止事件,汇总各种信息,自动生成包括压测基本信息等多维度信息的压测报告,节省了一些压测后分析的时间。


案例分享

以下以实际压测的过程来做个案例分享。


团队/服务注册

设定实施压测的虚拟团队和压测覆盖范围的应用服务。



链路治理

  • 选定压测链路入口,可以得到入口以下的接口链路关系树,便于梳理。

  • 明确需要 Mock 的外部接口,并做配置,参考“链路治理模块设计”一节。



应用改造与压测配置

  • 对待接入压测应用改造,满足“服务的可压测条件”,参考图 7。

  • 压测应用依赖中间件配置,系统依据构建的链路信息,能够自动发现。提供统一配置和核对的页面功能。



Quake 准备

压测自动化系统是基于 Quake 构建的,流量录制、回放、施压等依赖于此。因此需要到 Quake 上配置流量录制的“流量任务”和压测执行的“压测场景”。



数据构造

配置数据构造逻辑,当然已有的逻辑都是可复用的单元,可以先查看已有逻辑是否能满足自己的需要。



配置数据构造流程。



压测实施

设定压测计划,到启动时间,系统会自动启动压测。



压测中,注意关注压测验证校验的告警信息,及时处理。



压测后,可查看压测报告。记录和跟进发现的问题。



总结与展望

目前,压测自动化系统已经投入使用,美团酒店和境内度假的全部团队已经接入,有效地提升了压测效率。后续会在两个大方向上持续建设升级,一个是把全链路压测放到“容量评估与优化”领域来看,不仅关注整体系统的稳定性,同时也期望兼顾成本的平衡;另一个是与稳定性其他子领域的生态集成,比如故障演练、弹性伸缩等等,在更多场景发挥压测的作用。最后,通过这些努力,使得线上系统的稳定性成为一个确定性的事情。




作者简介


欧龙,美团研发工程师,2013 年加入美团,目前主要负责境内度假交易稳定性建设等工作。


文章首发于公众号“美团技术团队”:https://mp.weixin.qq.com/s/uv2AfwnKzkSAMDjj9fs-UA


2019 年 4 月 04 日 15:593200

评论

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

Week10总结

熊威

SpringBoot系列(二):如何灵活使用SpringBoot

xcbeyond

Java 微服务 springboot

Django查看操作数据库的执行命令

BigYoung

数据库 django 操作

关于微服务架构的一些思考

俊俊哥

微服务

看前谷歌工程师是如何副业赚钱的?

非著名程序员

程序员 个人成长 副业赚钱 提升认知

Django中的session的使用

BigYoung

django session Cookie

奋斗在一线大城市的年轻人的生活工作实录(工厂蓝领篇)

Learun

程序员 软件开发 故事 企业信息化 短片小说

Week10作业1

熊威

安卓移动应用代码安全加固系统设计及实现

几维安全

android 安全评估 移动应用安全

云图说丨手把手教你为容器应用配置弹性伸缩策略

华为云开发者社区

Docker 云计算 Kubernetes 容器 云容器引擎

普通工程师简史

郭华

SpringBoot系列(三):SpringBoot特性_SpringApplication类(自定义Banner)

xcbeyond

Java 微服务 springboot Banner

微服务框架 Dubbo

莫莫大人

极客大学架构师训练营

智能汽车安全风险及防护技术分析

几维安全

移动应用安全

HTML5CSS3前端入门教程---从0开始通过一个商城实例手把手教你学习PC端和移动端页面开发第10章有路网PC端主页实战整合

Geek_8dbdc1

HTML5+CSS3前端入门教程---从0开始通过一个商城实例手把手教你学习PC端和移动端页面开发第11章有路网移动端主页实战

Geek_8dbdc1

致远互联A6+Cloud C位出道 赋能中小企业乘风破浪

爱极客侠

Windows AD日志分析告警平台—WatchAD安装教程

BigYoung

监控 windows 日志 AD 告警

JAVA位运算

彭阿三

Java 位运算

神经网络的学习为何要设定损失函数?

王坤祥

神经网络 学习 损失函数

《深度工作》学习笔记(6)

石云升

读书笔记 专注 深度工作

解析中美数字货币竞争战略 | 构建属于“人类命运共同体”的货币体系

CECBC区块链专委会

数字货币 人民币

核心稳定、易扩展——开放关闭原则(The Open-Closed Principle)

晃来晃去的萨麦尔

编程习惯 架构分析 软件设计原则

SpringBoot 系列(一):SpringBoot项目搭建

xcbeyond

Java 微服务 springboot

DSN 主流项目调研 3——Orbit数据库的故事

AIbot

区块链 分布式存储 IPFS 分布式文件 Orbit

React TypeScript 项目基本构建2

JackWangGeek

React

有限数据量如何最大化提升模型效果?百度工程师构建数据增强服务

百度大脑

人工智能 数据 模型训练 百度大脑

架构师训练营 第 10 周 作业&总结

Jam

微软看上的Rust 语言,安全性真的很可靠吗

华为云开发者社区

数据库 开源 rust 安全 代码

《深度工作》学习笔记(完)

石云升

读书笔记 时间管理 专注 深度工作

DSN 主流项目调研 2——Sia和SAFE Network

AIbot

区块链 分布式存储 分布式文件存储 Sia SAFENetwork

演讲经验交流会|ArchSummit 上海站

演讲经验交流会|ArchSummit 上海站

美团全链路压测自动化实践-InfoQ