“AI 技术+人才”如何成为企业增长新引擎?戳此了解>>> 了解详情
写点什么

稳定性全系列(二):如何做线上全链路压测

  • 2020-03-25
  • 本文字数:3164 字

    阅读完需:约 10 分钟

稳定性全系列(二):如何做线上全链路压测

1. 背景介绍

如今,在微服务架构盛行的互联网时代,微服务架构下模块(本文指可独立部署的服务)之间的关系错综复杂(哪怕是避免模块之间的直接循环依赖都很变得困难),评估一整套业务系统(集群)的容量已经不像评估单机系统那样容易,而系统的容量评估,是稳定性建设的核心内容之一,是我们绕不开的主题。


有了系统容量评估,配合今年的业务目标,我们才知道应该申请多少预算、什么时候需要扩容、系统瓶颈在哪、哪些服务(模块)需要扩容。评估系统容量或者准确的说 评估线上系统的容量现阶段最优效也是最准确的方式就是进行线上全链路压测

2. 准备工作

你要问实现线上全链路压测难不难?当然难(现阶段稳定性工作哪一项不难?),但依然有迹可循。而且和当前技术体系的系统化建设程度以及各团队之间协作有关系。想实现线上全链路压测,我们需要做如下三个方面的准备工作(为了描述简单,本文的“全压”指的是线上全链路压测):


  • 确定需要哪些团队参与

  • 确定全压技术方案

  • 设定全压目标和计划

3. 拆分详情

确定需要哪些团队参与

全压绝对是一项耗时耗力的工程,特别是刚开始的时候。首当其冲的当然是得到老大的支持,一般需要参与进来的至少有 研发测试运维 三个团队。研发团队主要负责技术方案的设定和实施(当然如果有架构组或中间件团队,技术方案的设定可以交给他们),测试团队负责验证全压方案和数据的正确性以及真正的施压,而运维团队需要关注压测对线上集群的影响以及一些辅助工作(例如提前调整网关的限流阈值)。

确定全压技术方案

这一步应该是难度最大的,不同技术体系具体实施方案当然不一样,但可以相互参考,就拿我的业务部门举例,我们服务端是 Java 栈,整个业务流量符合如下链路:



上图最左边的 App 指的是用户手机中装的 App,从后面的链路我们可以看出,业务网关后面就是我们的服务端系统,各模块之间使用 Dubbo 来进行交互,当然异步用的是 DDMQ,而当模块需要使用集团的中台服务时,我们使用的是 HTTP。模块内部还使用了线程池,也使用了 MySQL、Redis 等外部服务。


第一步,确定“全链路”应该包含链路(或顶级接口),所谓的全链路,它其实是一个相对的概念,在刚开始做全压时,我们主要是把线上的核心链路找出来,找到这些链路的顶级接口,这其实就是发压的主要入口。


第二步,确保压测标识在这些链路中传递以及处理,第二步是最难的也是最复杂的,我们要分析第一步中这些链路中如何有效安全的传递压测标识,压测标识是系统中用来区分压测流量还是线上正常流量的标识,我们要保证压测标识正确的传递和清除,否则可能导致严重的线上事故。这里将给出我们的做法,供大家参考,主要分四大部分:


  • 尽可能的对模块无侵入或低侵入


微服务架构下可独立你部署的模块数可能会非常惊人,任何能成功实时的技术方案都应该要求是对业务模块是无侵入或者是低侵入的,否则将影响方案的推广以及实施成本,我们为了做到这一点,打算直接在我们的基础组件(内部使用的公共库和中间件)动刀子,尽可能的对用户透明。


  • 压测标识安全的传递和处理


这个要分模块内、模块间、模块外三个部分来考虑:


模块内:假如模块内部已经知道该流量是压测流量,我们如何保证该压测流量能在模块内部复杂的逻辑处理中不丢失?模块内主要考虑的是线程中和跨线程执行的时候,压测标识容易丢失,线程中,我们使用的是对 ThreadLocal 的包装类(我们没使用阿里开源的 TransmittableThreadLocal)。而为了能够跨线程传递,我们修改了 taxi-thread 公共库,将其中的 TaxiThreadPoolExecutor 等类进行了修改,加入了压测标识的传递(这里补充下背景,我们为了 traceId 能跨线程传递,在 taxi-thread 公共库中包装了 JDK 线程池相关的类,并在开发规范中要求研发同学不能直接使用 JDK 原生的线程池)。还有一块,就是日志打印,为了能准确区分压测流量和正常流量,也为了压测流量不污染线上数据(比如线上很多模块有埋点日志),我们修改了 taxi-log(我们这边没有直接使用 SLF4J,而是使用包装过的日志公共库 taxi-log),将压测流量所有的日志打在原日志目录下的 shadow 影子目录下,这一切对用户也是透明的。


模块间:我们这边模块间的通讯方式主要是 Dubbo 和 DDMQ,Dubbo 这块的话我们直接通过 Filter 来实现压测标识传递,而 DDMQ 本身就自带压测标识传递方式,可以直接使用。


模块外:这一部分主要是存储、缓存以及一些外部服务(比如上图的中台服务)。


存储例如 MySQL、MongoDB 等,我们必须要隔离压测和线上数据,所以我们会事先建好所谓的 影子表,影子表其实和线上表的区别就是表名,影子表会在真实表名前加一个 shadow_前缀,而我们的 taxi-mybatis、taxi-mongo 等公共库在识别到压测标识时,会给表或者文档名称前也带上 shadow_前缀。之所以只是做表隔离而没有做库级别隔离,考虑到的还是降低侵入性和成本。关于存储,还有一个关键点,假如模块只提供查询服务(比如某些配置中心),如果按照前面说的,存储接入压测标识这块做成无侵入的话,全压流量查询也会走影子表,这也许是我们不希望看到的,所以在 MySQL 这块我们特意做成有侵入的(需要加一个插件配置),否则默认不识别压测标识


对于分布式缓存,我们使用的是 Redis,这一块的处理方式和存储类似,我们修改了我们自己 Redis 包装的公共库,如果是识别到压测标识,默认在操作的 key 上加一个 shadow_前缀,保证压测流量不污染线上缓存数据。


对于外部服务,我们使用的是 HTTP 来调用,所以修改了我们 taxi-util 中的 HTTP 组件,做了压测标识的传递,保证下游外部服务能知道这是压测流量。那肯定有人问,如果下游服务不支持压测流量识别该咋办?所以这里我们借助了 SDS 服务降级系统https://github.com/didi/sds),可以只对压测流量进行拦截,使其不调用下游外部服务。


最后的效果如下:



第三步,确保全压流量能被监控到,这涉及到我们在实际全压中能否直观的感受到压测流量,这一块需要和内部的监控系统来打通,由于能方便的取到压测标识,这一块的实现我们不再阐述。


第四步,准备全压数据,确定接口调用比例,最理想的方式是能对线上流量进行克隆、放大和处理,作为压测输入数据来重放,但这块难度较大,需要有好的平台来支撑,我们目前只能使用更简单的方式来造数据。由于无法使用仿真数据,我们提前在影子表中造了一批用户、设备信息、位置等和业务相关的数据,然后去线上统计了链路上各顶级接口的流量和交易量的比例,来作为压测时流量放大的依据。当然,必不可少的还有一个发压工具或平台,例如滴滴的奥创发压平台。

确定全压目标和计划

全压前我们需要定下全压的目标,比如当前我们交易系统能支撑 100W 订单(现有日单量峰值),而业务今年的目标是冲击 300W 日订单,那按照峰值流量 2 倍来算,我们的交易系统需要支撑 600W 的单量,那么第一次全压的目标可以保守些,定为日订单 200W。因为哪怕线下验证已经充分,全压时也会遇到各种出乎意料的问题,当然发现问题其实也意味着我们发现了系统容量瓶颈,这也是全压的主要目的之一。全压计划也同样重要,因为我们系统一定是在不断的迭代中,上一次的全压结论可能会很快“过期”,所以我们需要定下明确的全压计划和节奏,不断降低全压的人力成本,使这一稳定性建设工作持续有效的进行下去。

4. 总结

截止到目前,我们已经进行过很多轮的全压,也在不断往全压中补充新的链路,加入新的模块,目前全压的人力成本还是较高,我们也在探索全自动化全压方案,到时候有成果将和大伙继续分享。


作者介绍


易振强,滴滴专家工程师


我是易振强,热爱开源,热爱分享,深耕分布式系统和稳定性建设,欢迎关注 SDS 服务降级系统:https://github.com/didi/sds ;也热爱生活,热爱漫画,一拳超人和海贼王都很好看!!


本文转载自公众号普惠出行产品技术(ID:pzcxtech)。


原文链接


https://mp.weixin.qq.com/s/2M9EyCIuT1mZ9drftdMEBA


2020-03-25 10:003597

评论

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

有什么方法从 PostgreSQL 数据迁移到 TiDB ?

TiDB 社区干货传送门

迁移 实践案例 管理与运维

KaiwuDB 数据服务平台 1.0 产品详解

KaiwuDB

时序数据库 多模数据库 数据服务平台

亚信科技AntDB数据库荣获2022年度技术卓越奖

亚信AntDB数据库

AntDB 国产数据库 AntDB数据库

FL Studio2024中文完整版电脑编曲软件及配置要求

茶色酒

FL Studio FL Studio 21

easyrecovery2024非常好用的磁盘恢复工具

茶色酒

EasyRecovery EasyRecovery15 easyrecovery2023

MySQL:如果被更新字段的新值与旧值相等,SQL会被真正执行吗?

程序员拾山

MySQL

WSL中使用vcpkg安装pcl库出现编译失败的原因

大伟

Best Wishes「兔」You!

阿里云视频云

TiDB CDC v6.5.0 新特性实践

TiDB 社区干货传送门

实践案例 新版本/特性发布 6.x 实践

Java高手速成 | 多态性实战

TiAmo

编程语言 多态 Java 开发

AntDB数据库助力中国移动结算中心建设

亚信AntDB数据库

AntDB 国产数据库 AntDB数据库

AirServer2023下载安装教程投屏软件,支持安卓、苹果手机投屏至电脑

茶色酒

AirServer AirServer2023

【Java应用服务体系】「序章入门」全方位盘点和总结调优技术专题指南

洛神灬殇

Java 技术分析 应用调优 优化指南

2022大数据产业年度“国产化优秀代表厂商”榜单发布,亚信科技AntDB数据库位列其中

亚信AntDB数据库

AntDB 国产数据库 AntDB数据库

2022年的魔力象限领导者,为什么是华为数通?

脑极体

华为

工信部电子标准院:龙蜥操作系统获评“优秀”

OpenAnolis小助手

工信部 开源项目 获奖 龙蜥操作系统 生态构建

tomcat8和tomcat7性能比较

五毛

tomcat 压测分析

复习前端:浏览器缓存策略

devpoint

Service Worker 浏览器缓存 缓存技术

MySQL统计总行数:听说count(*)性能更好,是真的吗

程序员拾山

MySQL

从管事到管人

石云升

极客时间 1月月更 技术领导力实战笔记

2022下半年盘点:20+主流数据库重大更新及技术要点汇总

亚信AntDB数据库

AntDB 国产数据库 AntDB数据库

中原银行对金融行业实时数仓的现状与发展趋势思考

Apache Flink

大数据 flink 实时计算

【最佳实践】TiDB 同步&迁移实战 (从 MySQL/Oracle/PostgreSQL/MongoDB 到 TiDB )

TiDB 社区干货传送门

二十年,三条路:国产CPU的“饱和式救援”

脑极体

cpu

英特尔2022技术创新和产品发布盘点:深耕硬核创新,助推数字未来

科技热闻

TiDB PPT玩家快速点评 V6.5 新特性

TiDB 社区干货传送门

版本测评

TiCDC 源码解读(4)-- TiCDC Scheduler 工作原理解析

TiDB 社区干货传送门

TiCDC 源码解读

C#/VB.NET 在 Word 表格中插入或提取图像

在下毛毛雨

C# .net 提取图像 word表格 添加图片

“信”创未来 | AntDB数据库2022年度总结,请查收!

亚信AntDB数据库

AntDB 国产数据库 AntDB数据库

2022 年行摄回忆录

穿过生命散发芬芳

摄影 行摄回忆录

从员工批量离职中,认识管理的价值

石云升

极客时间 1月月更 技术领导力实战笔记

稳定性全系列(二):如何做线上全链路压测_架构_易振强_InfoQ精选文章