全链路压测

2023-11-17

核心流程

全链路压测实施的核心流程如下:

骤一:确定压测目标

压测目标主要包括压测范围、策略、目的,往往与业务、技术目标息息相关。例如:

  • 压测范围:用户注册加登录,为大规模拉新做准备。
  • 压测策略:高仿真生产环境压测,提前经历真实的业务高峰。
  • 压测目的:探测业务吞吐极限,验证架构能力、探测性能瓶颈。

步骤二:梳理系统架构

梳理清楚端到端的请求链路、技术架构、分层结构、模块划分,以及RPC、消息、缓存、数据库等中间件的使用情况,分析潜在的瓶颈点,并针对性的增加监控指标、制定应急预案。

本文示例的系统架构图如下:

组件

分类

潜在的瓶颈、问题

SLB

负载均衡

  • 容量不足
  • 建连失败

ApiGateway

API网关

  • 容量不足
  • 线程等待
  • 触发限流

UserService

微服务

  • 容量不足
  • 线程池资源耗尽
  • 日志资源耗尽
  • 触发限流
  • GC

SecurityService

微服务

  • 容量不足
  • 线程池资源耗尽
  • 日志资源耗尽
  • 触发限流
  • 消费延迟
  • GC

Redis

KV缓存

  • 容量不足
  • 触发限流
  • 缓存击穿
  • 缓存热点
  • 连接池耗尽
  • 大对象

MySQL

数据库

  • 容量不足
  • 触发限流
  • 连接池耗尽
  • 慢SQL

Kafka

消息队列

  • 容量不足
  • 消息堆积
  • 磁盘写达到100%

SmsService

第三方依赖

第三方可能会拒绝参与压测

步骤三:梳理业务模型

压测的业务模型对压测结果的准确性至关重要。全链路压测的链路代表要压测的业务范围,同一条链路需要构造海量的参数集合代表不同用户的不同行为,系统的基础数据、系统预热情况等代表系统的状态。链路范围、链路的访问量级、链路的参数集合、基础数据、预热情况一起构成了压测的业务模型。

通常从以下维度梳理业务模型:

  • 用户行为维度
    • 确定业务接口的范围、接口的目标量级、接口的参数集合、压力曲线等。
    • 根据业务特性确定压测数据的分布。例如用户的规模和地域、商品的种类和数量、是否制造热点商家和商品等。
  • 系统状态维度
    • 根据业务和场景的特性,确定各组件(例如缓存)的状态。例如拉新场景,缓存命中率非常低,而日常高峰场景,缓存命中率非常高,需要根据不同的场景来准备不同的缓存预热策略。
    • 根据业务和场景的特性,确定基础数据的量级和范围。例如拉新场景,需要考虑老用户召回的情况,而日常高峰场景,一般准备与活跃用户相当量级的基础数据。

总之,业务模型与业务强相关,压测的业务模型对压测结果的准确性至关重要。

步骤四:准备压测脚本

根据业务场景编写压测脚本,也可以直接复用已有脚本

步骤五:改造升级环境

在生产环境进行全链路压测,最核心的是线上写操作不能污染正常的业务数据。因此,需要针对存储做影子库表,即正常业务库表的镜像,让压测流量的数据流转到影子库表,正常业务流量流转到正常业务库表,在逻辑上隔离两种流量,使之互不影响。

生产环境压测的三大前提:

  • 压测标记不丢失

压测流量在任何环节能够被正确的识别出来。在流量入口层带上压测标,中间件识别并继续往下传递压测标,保证整条链路上压测标不丢失,通过这种方式使得下游的应用和存储也能接收到压测标。

  • 压测流程不中断

压测流量能够正常的调用下去,整个流程不被阻断,返回符合预期的业务结果。业务的应用层,要支持全链路也需要进行对应的改造。应用层在识别到压测标时,需要绕过参数校验、安全校验等校验逻辑,例如手机号格式校验、用户状态校验、以及一些其它特殊业务校验逻辑。

  • 压测数据不污染

压测数据不对线上正常的业务造成数据污染。全链路场景往往包含多个读写场景,为了隔离压测数据,存储中间件识别到压测标之后,将数据写入影子库表,与真实的数据区分开。为了更加真实的模拟真实场景,影子库表中的基础数据(例如买家、卖家、商品、店铺等)是由真实数据加上固定偏移量构造而成,迁移过程中会进行采样、过滤、脱敏等操作保证数据安全,一般在数据量级上和真实数据保持一致。

PTS探针已经具备以上三大能力,仅需在应用上部署好探针、配置好规则即可,无需改动业务代码。

本文示例的架构图升级方案如下:

步骤六:正常流量联调

通常通过执行功能回归用例完成联调,是需要将正常回归流量打上流量标(例如在请求中添加Header x-pts-test=2),这样在查找调用链路时可以精准定位。该环节主要关注点如下:

  • 验证探针对正常业务逻辑无影响,用例的测试结果均符合预期。
  • 验证探针对依赖组件的适配情况,无遗漏的RPC调用、采集的数据准确无误;调用链完整性是全链路压测数据安全的核心。
  • 将探针采集的调用链数据进行聚合(建议500+以上),抹平不同参数、不同逻辑分支带来的调用链差异性。使用聚合后的依赖拓扑图辅助梳理组件依赖可以极大程度的避免组件遗漏。
  • 根据正常流量联调的结果,需要梳理出影子库表的范围、第三方服务的依赖情况。

步骤七:准备压测数据

注意 压测数据准备存在很高的风险,请与DBA、相关人员联系,确保相关数据库、中间件的容量、性能、资源足以支撑压测数据的迁移、存储,以及后续的压测计划。

  1. 确认影子库表范围。

影子库表的范围就是压测链路涉及到的应用使用到的库表。在梳理过程中,需要包括库名、表名、数据量级、核心业务字段(例如商品ID、用户ID等),表与表之间字段的关联性(外键、JSON字段中的引用等均包括在内)。

  2.确认偏移字段、脱敏字段。

偏移字段:字段偏移可以极大的保证业务数据的安全。偏移字段一般选择用户ID、商品ID等关联字段,如果有用到Sequence类的分布式ID组件,也需要进行偏移。根据业务的实际增长选择不同的偏移量,一般会选择10年以上都不会用到的值作为偏移量。

具体的偏移量需要根据业务增长和数据类型确定,常见的偏移方式如下:

说明 脱敏字段:业务上认为是敏感数据的用户数据,例如手机号、密码、用户名等,不同安全级别的字段会有不同的脱敏方式,根据业务要求脱敏即可。常见的脱敏方式包括遮盖掩码、加盐哈希、高斯噪音等。需要确保脱敏之后的字段值在业务流程上是能走通的,如果在压测联调过程中出现校验失败,可以使用Mock规则绕过校验。

新建影子库表。

说明 该步骤一般由DBA完成,根据影子库表范围创建库表结构。

4.执行数据迁移。

说明 该步骤一般由DBA完成,迁移工具一般选择DataX,在业务低峰时段从备库迁移到影子库表,建议根据实际情况配置限流。迁移的数据量一般与线上数据保持数据量级上一致即可。

5.准备接口参数数据。

基于基础数据和压测模型构造业务接口的参数集合。根据各压测平台的不同,支持的格式、配置方式也各有不同,一般都支持CSV文件格式,根据各平台要求构造即可。

压测业务模型对压测结果的准确性至关重要,而压测数据准备是业务模型落地的核心环节。压测数据主要包括基础数据和链路数据两种。

  • 基础数据:包括业务运行所需的库表和数据,例如:买家、卖家、商品、优惠等,基础数据的规模一般需要与实际业务数据在量级上保持一致。
  • 链路数据:包括需要压测的接口和多样化的接口参数集合,接口请求的参数集合是基于基础数据生成的。例如:商品详情页的接口为https://xxx.com/item?itemId=xxx,参数集合为具体的商品ID的集合。

基础数据的准备方式通常有直接构造和数据迁移两种:

  • 直接构造:直接根据业务规则构造出来,一般用在少量数据的准备,例如联调阶段的数据构造。
  • 数据迁移:对线上数据做清洗、采样、偏移后迁移到影子库表,数据完备性好,仿真度高,省时省力。建议使用DataX进行数据迁移。

数据准备环节,最核心的原则是需要保证镜像、影子库表的软硬件配置与正常库表一致,同时配置简单易行。这样可以保证在压测的时候充分暴露线上的数据库表的真实问题。

选择数据隔离策略有以下方式:

  • 影子表隔离:在生产库建立业务表同结构的影子表,影子表名通常会在正常表名的基础上加上固定的前后缀。表级别的隔离在设计上允许复用一部分只读表,但是梳理难度有所增加。
  • 影子库隔离:在用一个实例上创建与源数据库同配置的影子库,影子库名通常会在正常库名的基础上加上固定的前后缀,表名保持不变。库级别的隔离是数据源的隔离,隔离相对比较彻底、安全。
  • 影子Key隔离:一般用在KV缓存、存储组件上(例如Redis),探针会拦截对KV缓存、存储组件的所有操作,根据流量标自动修改Key和过期时间,达到隔离数据和数据清理的目的。

其他存储组件的隔离原理基本上与上述三种思路上一致,您可以根据自身业务和架构特性,自行选择最佳的隔离方式。

步骤八:联调压测流量

  1. 根据步骤七:准备压测数据中梳理的库表情况,在控制台填写影子规则,不同规则需要填写的字段不尽相同。
  2. 根据步骤六:正常流量联调中梳理的第三方服务依赖情况在控制台配置Mock规则。如果需要使用复杂的动态响应结果,需要申请部署MockServer。

与正常流量联调的方式基本一致,联调过程中需要将压测流量打上流量标(例如在请求中添加Header x-pts-test=1),在查找调用链时可以精准定位。该环节主要关注点如下:

  • 验证业务逻辑是否正常,用例的测试结果均需符合预期。此环节受基础数据影响比较大,容易出现某个字段不符合某些校验逻辑而导致业务进行不下去。
  • 验证压测流量产生的调用链是否与正常流量一致,如果不一致需要相关人员介入排查原因。
  • 验证影子隔离和Mock规则是否有效,如果有正式表存在测试数据写入或者影子表有正常数据写入,则需要相关人员介入排查原因。

步骤九:单链路小流量试压

开始全链路压测。不同的业务、压测目标往往对应不同的压测节奏和方法,不可一概而论。除了注意以下要点之外,还需根据业务、架构、人员等自身情况,制定不同的压测计划,在尽量避免线上故障的前提下,发现更多的线上问题。

  • 制定明确的压测计划、压测通过标准,相关人员必须现场支持,分工明确,统一指挥。
  • 线上压测应在业务低峰时段进行,并制定应急预案。
  • 应当具备监控大盘,密切关注相关监控指标。
  • 遵循循序渐进的原则,单链路压测>小流量验收>全链路验收。

对生产环境进行小流量试压,暴露最表层的问题,保证流程的正确性。

步骤十:单链路压测

验证所有接口在无干扰、无竞争的情况下的性能基线数据,确定所有接口的性能SLA。

步骤十一:全链路小流量试压

对生产环境进行小流量试压,暴露最表层的问题,保证流程的正确性。

步骤十二:全链路压测并验收

按生产环境流量配比进行复合场景全链路压测。探测相互干扰、竞争情况下的资源消耗水位和瓶颈。大致上分为以下5个阶段:

  1. 阶梯加压与容量规划。

定位性能瓶颈;拿到各应用的性能基线数据与容量,获取限流阈值。

  1. 瞬时加压。

验证系统预热是否合理,比如数据库连接、RPC连接、业务缓存、JIT预编译等。

  1. 稳定性测试。

验证系统资源使用是否合理,是否存在内存泄漏等情况。

  1. 故障演练。

通过人工注入故障,暴露架构的稳定性问题,提升系统的健壮性。

5.验证限流、降级、预案的有效性,产出最终的交付物。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

全链路压测 的相关文章

  • Mockito:如何通过模拟测试我的服务?

    我是模拟测试新手 我想测试我的服务方法CorrectionService correctPerson Long personId 实现尚未编写 但这就是它将执行的操作 CorrectionService将调用一个方法AddressDAO这将
  • 动态选择端口号?

    在 Java 中 我需要获取端口号以在同一程序的多个实例之间进行通信 现在 我可以简单地选择一些固定的数字并使用它 但我想知道是否有一种方法可以动态选择端口号 这样我就不必打扰我的用户设置端口号 这是我的一个想法 其工作原理如下 有一个固定
  • 如何使用assertEquals 和 Epsilon 在 JUnit 中断言两个双精度数?

    不推荐使用双打的assertEquals 我发现应该使用带有Epsilon的形式 这是因为双打不可能100 严格 但无论如何我需要比较两个双打 预期结果和实际结果 但我不知道该怎么做 目前我的测试如下 Test public void te
  • org.apache.hadoop.security.AccessControlException:客户端无法通过以下方式进行身份验证:[TOKEN,KERBEROS] 问题

    我正在使用 java 客户端通过 Kerberos 身份验证安全访问 HDFS 我尝试打字klist在服务器上 它显示已经存在的有效票证 我收到的异常是客户端无法通过以下方式进行身份验证 TOKEN KERBEROS 帮助将不胜感激 这是一
  • Java 公历日历更改时区

    我正在尝试设置 HOUR OF DAY 字段并更改 GregorianCalendar 日期对象的时区 GregorianCalendar date new GregorianCalendar TimeZone getTimeZone GM
  • Java 集合的并集或交集

    建立并集或交集的最简单方法是什么Set在 Java 中 我见过这个简单问题的一些奇怪的解决方案 例如手动迭代这两个集合 最简单的单行解决方案是这样的 set1 addAll set2 Union set1 retainAll set2 In
  • 没有 Spring 的自定义 Prometheus 指标

    我需要为 Web 应用程序提供自定义指标 问题是我不能使用 Spring 但我必须使用 jax rs 端点 要求非常简单 想象一下 您有一个包含键值对的映射 其中键是指标名称 值是一个简单的整数 它是一个计数器 代码会是这样的 public
  • volatile、final 和synchronized 安全发布的区别

    给定一个带有变量 x 的 A 类 变量 x 在类构造函数中设置 A x 77 我们想将 x 发布到其他线程 考虑以下 3 种变量 x 线程安全 发布的情况 1 x is final 2 x is volatile 3 x 设定为同步块 sy
  • tomcat 中受密码保护的应用程序

    我正在使用 JSP Servlet 开发一个Web应用程序 并且我使用了Tomcat 7 0 33 as a web container 所以我的要求是tomcat中的每个应用程序都会password像受保护的manager applica
  • 如何访问JAR文件中的Maven资源? [复制]

    这个问题在这里已经有答案了 我有一个使用 Maven 构建的 Java 应用程序 我有一个资源文件夹com pkg resources 我需要从中访问文件 例如directory txt 我一直在查看各种教程和其他答案 但似乎没有一个对我有
  • 在我的 Spring Boot 示例中无法打开版本 3 中的 Swagger UI

    我在 Spring Boot 示例中打开 swagger ui 时遇到问题 当我访问 localhost 8080 swagger ui 或 localhost 8080 root api name swagger ui 时出现这种错误 S
  • Java 和 Python 可以在同一个应用程序中共存吗?

    我需要一个 Java 实例直接从 Python 实例数据存储中获取数据 我不知道这是否可能 数据存储是否透明 唯一 或者每个实例 如果它们确实可以共存 都有其单独的数据存储 总结一下 Java 应用程序如何从 Python 应用程序的数据存
  • logcat 中 mSecurityInputMethodService 为 null

    我写了一点android应显示智能手机当前位置 最后已知位置 的应用程序 尽管我复制了示例代码 并尝试了其他几种解决方案 但似乎每次都有相同的错误 我的应用程序由一个按钮组成 按下按钮应该log经度和纬度 但仅对数 mSecurityInp
  • 获取文件的总大小(以字节为单位)[重复]

    这个问题在这里已经有答案了 可能的重复 java 高效获取文件大小 https stackoverflow com questions 116574 java get file size efficiently 我有一个名为 filenam
  • 关键字“table”附近的语法不正确,无法提取结果集

    我使用 SQL Server 创建了一个项目 其中包含以下文件 UserDAO java public class UserDAO private static SessionFactory sessionFactory static se
  • 如何使用 jUnit 将测试用例添加到套件中?

    我有 2 个测试类 都扩展了TestCase 每个类都包含一堆针对我的程序运行的单独测试 如何将这两个类 以及它们拥有的所有测试 作为同一套件的一部分执行 我正在使用 jUnit 4 8 在 jUnit4 中你有这样的东西 RunWith
  • 我如何在java中读取二进制数据文件

    因此 我正在为学校做一个项目 我需要读取二进制数据文件并使用它来生成角色的统计数据 例如力量和智慧 它的设置是让前 8 位组成一个统计数据 我想知道执行此操作的实际语法是什么 是不是就像读文本文件一样 这样 File file new Fi
  • 干净构建 Java 命令行

    我正在使用命令行编译使用 eclipse 编写的项目 如下所示 javac file java 然后运行 java file args here 我将如何运行干净的构建或编译 每当我重新编译时 除非删除所有内容 否则更改不会受到影响 cla
  • 在java中为组合框分配键

    我想添加一个JComboBox在 Swing 中这很简单 但我想为组合中的每个项目分配值 我有以下代码 JComboBox jc1 new JComboBox jc1 addItem a jc1 addItem b jc1 addItem
  • Spring Boot 无法更新 azure cosmos db(MongoDb) 上的分片集合

    我的数据库中存在一个集合 documentDev 其分片键为 dNumber 样本文件 id 12831221wadaee23 dNumber 115 processed false 如果我尝试使用以下命令通过任何查询工具更新此文档 db

随机推荐

  • Python中利用compileall将py项目打包成pyc项目

    在进行python项目开发的时候一定会涉及到项目打包这个环节 有时因为一些依赖的原因没法打包成一个大的可执行文件 但为了代码的安全性我们最起码需要打包成pyc的预编译格式 这样运行者 一般是测试和线上部署 在无法看到程序源码的同时也能顺利执
  • numpy.c_和numpy.r_的用法

    numpy c 将切片对象沿第二个轴 按列 连接 np c np array 1 2 3 np array 4 5 6 array 1 4 2 5 3 6 np c np array 1 2 3 0 0 np array 4 5 6 arr
  • UML类图几种关系的总结

    在UML类图中 常见的有以下几种关系 泛化 Generalization 实现 Realization 关联 Association 聚合 Aggregation 组合 Composition 依赖 Dependency 1 泛化 Gene
  • 子类加@Data后,IDEA调试时“出现”父类属性无值

    项目场景 自测一个功能的时候 IDEA调试同过对象的VIEW查看对象内容 发现加了 Data的返回子类型中父类的属性没有出现 问题描述 父类Response中的返回VO对象 Data public class PVO private Sti
  • 链式存储之:链表的引出及其简介

    上篇博客 笔者讲解了一下顺序表ArrayList 对于ArrayList有想法的各位老铁可以看一下 值得思索的 ArrayList和线性表 你确定错过这次机会 念君思宁的博客 CSDN博客值得思索的 ArrayList和线性表 你确定错过这
  • python格式化

    python格式化是python语法中很基础也是很重要的知识 本文介绍了python格式化的几种方法仅供参考 一 格式化方法1 格式为 输出内容 对应的变量1 对应的变量2 其中 d表示整数类型 s表示字符串类型 f表示浮点类型 例子 设以
  • 半实物仿真测试方法、装置及系统与流程

    机器人控制器的测试主要包括控制器核心软件的测试和外部接口的测试 同时为了保证机器人控制器在真实工况下进行测试 需要对其实际运行的各项功能和性能指标进行测试 半实物仿真测试平台是连接控制器和被控对象进行测试的测试平台 在基于半实物仿真的实验中
  • 数据清洗:让数据更纯净,Python实战 机器学习&深度学习

    目录 步骤1 导入必要的库 步骤2 加载数据 步骤3 处理缺失值 3 1 删除含有缺失值的行
  • 给应届生开出20K月薪,看到招聘要求后,我傻眼了......

    一到秋招季 就有 灵异 事件发生 应届生痛斥找不到工作 精心准备的简历投了几十家过不了网申 而企业控诉招不到人才 今年明明扩招了 应届生be like 这些岗位都挺适合我的 简直一个量身打造 用人单位be like 岗位要求门槛写得也不高
  • MySQL数据库迁移快速导出导入大量数据(外发)

    数据库迁移是我们经常可遇到的问题 对于少量的数据 迁移基本上不会有什么问题 生产环境中 有以下情况需要做迁移工作 磁盘空间不够 比如一些老项目 选用的机型并不一定适用于数据库 随着时间的推移 硬盘很有可能出现短缺 业务出现瓶颈 比如项目中采
  • vue-cli3打包项目

    vue cli3打包项目 使用vue cli3开发好项目后 就可以将它打包 这样就可以通过输出文件中的index html来访问该项目了 在打包项目之前需要先修改两个文件 分别是vue config js router index js 如
  • 【C++】【TensorRT】检测时间不稳定原因汇总(持续更新)

    本人使用C 版本的TensorRT框架做模型部署的开发工作 在实际上线具体的项目过程中碰到过检测时间不理想的情况 所以本人专门为此写一篇博客记录曾经遇到过的坑以及对应的解决方案 一 相同型号的机器和显卡检测时间不同 1 问题描述 两台相同型
  • 一文掌握JS 事件循环(Event Loop)

    作为前端开发者 事件循环 Event Loop 是必须掌握的内容 它是前端极其重要的基础知识 在日常的工作或者面试中也是一个非常高频的话题 理解 JavaScript 的事件循环往往伴随着宏任务和微任务 JavaScript 单线程执行过程
  • 模电基础(2)半导体二极管

    1 二极管的组成 二极管 将PN结封装起来 引出两个电极就构成了半导体二极管 二极管的常见结构包括 点接触型 图a 面接触型 图b 平面型 图c 点接触型 结面积小 不可通过较大的电流 结电容小 工作频率高 面接触型的结面积变大 所允许的电
  • Go语言网络编程(socket编程)http编程

    1 http编程 1 1 1 web工作流程 Web服务器的工作原理可以简单地归纳为 客户机通过TCP IP协议建立到服务器的TCP连接 客户端向服务器发送HTTP协议请求包 请求服务器里的资源文档 服务器向客户机发送HTTP协议应答包 如
  • 基于滑模控制的永磁同步电机直接转矩控制学习

    导读 针对传统的DTC存在的问题进行 本期主要介绍基于滑模控制的永磁同步电机直接转矩控制 如果需要文中的仿真模型 关注微信公众号 浅谈电机控制 获取 传统DTC采用两个 Bang bang 控制器分别对转矩和磁链幅值进行控制 响应快速 对系
  • IDEA中的方法、数组和重载

    IDEA软件 常用快捷键 快捷键 功能 Ctrl Shift 选中代码注释 多行注释 再按取消注释 Ctrl Alt L 格式化代码 Alt Ins 自动生成代码 toString get set等方法 Alt Enter 导入包 自动修正
  • BSC链节点搭建 保姆级详细教程

    BSC链节点搭建 保姆级详细教程 文档最后修改日期 2023 06 24 一 服务器配置要求 官方建议配置 系统 Mac Linux CPU 16核 内存 64 GB 内存 带宽 50M以上 硬盘 大于2T固态SSD可用空间数据盘 本次搭建
  • CCPC2016长春J (hdu 5920 Ugly Problem)

    给一个数字 n 1 lt n lt 1e18 让你找一些数字加起来和为 n 数字个数不超过50个而且数字都是回文数字 每次找到大小最接近这个数的回文数即可 如6745888可以找到6745476 6960242可以找到6950595 用大数
  • 全链路压测

    核心流程 全链路压测实施的核心流程如下 骤一 确定压测目标 压测目标主要包括压测范围 策略 目的 往往与业务 技术目标息息相关 例如 压测范围 用户注册加登录 为大规模拉新做准备 压测策略 高仿真生产环境压测 提前经历真实的业务高峰 压测目