编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

互联网核心技术-全链路压测(全链路性能测试)

wxchong 2024-08-18 00:40:31 开源技术 11 ℃ 0 评论

能力目标

  • 全链路压测思想以及实现
  • 全链路跟踪的原理和实现
  • 常用的链路压测方案
  • 中间件如何来进行实现
  • SpringBoot starter 如何编写

全链路压测的意义


上图是 2012 年淘宝核心业务应用关系的拓扑图,还不包含了其他的非核心业务应用,所谓的核心业务就是和交易相关的,和钱相关的业务。这张图大家可能看不清楚,看不清楚才是正常的,因为当时的阿里应用数量之多、应用间关系之混乱靠人工确实已经无法理清楚了。

在真实的业务场景种,每个系统的压力都比较大,而系统之间是有相互依赖关系的,单机压测没有考虑到依赖环节压力都比较大的情况,会引入一个不确定的误差。这就好比,我们要生产一个仪表,每一个零件都经过了严密的测试,最终把零件组装成一个仪表,仪表的工作状态会是什么样的并不清楚。

链路压测方案刨析

线下压测

顾名思义就是在测试环境进行压测,且是针对一些重点项目这种测试手段,因为测试环境硬件资源以及压测数据与线上差别太大并且服务间依赖关系错综复杂,测试环境很难模拟且不够稳定,压测出来的数据指标参考价值不大,难以用测试环境得出的结果推导生产真实容量。

预生产环境压测



这个一般是将生成环境的硬件以及软件同步复制到与生产环境一份,然后对服务内部的外部调用接口进行拦截,然后进行压测这样可以评估出来生产环境的真实容量以及达到压测的目的,但是成本非常高,需要将生产环境的硬件完全的复制一份,并未维护成本非常高,部署的时候需要同步的在预生产环境进行部署,以及压测代码的更改。

引流压测

随着业务量的不断增长,考虑到线下测试结果的准确性,开始尝试生产压测,这种压测手段,我们称之为引流压测。事实上没有真正的模拟放大压力进行测试,而是一种通过缩小在线服务集群数的方式来放大单机处理量。比如一个业务系统的集群有100个节点,将其中90个节点模拟下线或转发流量到剩余的10个节点上实施压测。



引流压测的弊端在于,DB承受压力不变,上下游系统的压力不变。压测结果仅能代表单个应用的性能,但往往无法识别链路和架构级的隐患,而且在引流过程中倘若出现异常或突如其来的业务高峰,很容易造成生产故障。

全链路压测

随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务。互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发、可能使用不同的编程语言来实现、有可能布在了几千台服务器,横跨多个不同的数据中心。因此,就需要一些可以帮助理解系统行为、用于分析性能问题的工具,以便发生故障的时候,能够快速定位和解决问题,但是他的缺点也很明显就是需要的技术难度很高,需要克服流量染色数据隔离日志隔离风险熔断等技术难题,因位在生产环境压测,所以控制不好风险也是非常高的。

所以,在复杂的微服务架构系统中,几乎每一个前端请求都会形成一个复杂的分布式服务调用链路。一个请求完整调用链可能如下图所示:


四种压测方案对比




全链路压测概述

什么是全链路压测

基于实际的生产业务场景、系统环境(生产环境),模拟海量的用户请求和数据对整个业务链(通常是核心业务链)进行压力测试,并持续调优的过程。

解决什么问题

解决在业务场景越发复杂化、海量数据冲击下系统整个业务链的可用性、服务能力的瓶颈,以及容量规划等问题。

精确的容量规划

为什么需要容量规划

容量规划的目的在于让每一个业务系统能够清晰地知道:什么时候该加机器、什么时候应该减机器?双11等大促场景需要准备多少机器,既能保障系统稳定性、又能节约成本

容量规划四步走

1. 业务流量预估阶段:通过历史数据分析未来某一个时间点业务的访问量会有多大

2. 系统容量评估阶段:初步计算每一个系统需要分配多少机器

3. 容量的精调阶段:通过全链路压测来模拟大促时刻的用户行为,在验证站点能力的同时对整个站点的容量水位进行精细调整

4. 流量控制阶段:对系统配置限流阈值等系统保护措施,防止实际的业务流量超过预估业务流量的情况下,系统无法提供正常服务流量控制阶段:对系统配置限流阈值等系统保护措施,防止实际的业务流量超过预估业务流量的情况下,系统无法提供正常服务

进行全链路的性能监控

保证系统稳定性:可能提前预估系统存在的各种问题,提前模拟高并发场景,有备无患。

请求链路追踪,故障快速定位:可以通过调用链结合业务日志快速定位错误信息。

精准的容量评估:能够定位到最需要扩容的服务,帮助公司用最低的成本满足业务的性能要求

真实的性能验证:能够在生成环境以最真实的环境来验证系统的真是性能。数据分析,优化链路:可以得到用户的行为路径,汇总分析应用在很多业务场景。


如何展开全链路压测

业务模型梳理

  • 首先应该将核心业务和非核心业务进行拆分,确认流量高峰针对的是哪些业务场景和模块,针对性的进行扩容准备。
  • 梳理出对外的接口:使用MOCK(模拟)方式做挡板。
  • 千万不要污染正常数据:认真梳理数据处理的每一个环节,确保 mock 数据的处理结果不会写入到正常库里面

数据模型构建

数据的真实性和可用性:可以从生产环境完全移植一份当量的数据包,作为压测的基础数据,然后基于基础数据,通过分析历史数据增长趋势,预估当前可能的数据量

数据隔离:千万不要污染正常数据:认真梳理数据处理的每一个环节,可以考虑通过压测数据隔离处理,落入影子库,mock 对象等手段,来防止数据污染

压测工具选型

使用分布式压测的手段来进行用户请求模拟,目前有很多的开源工具可以提供分布式压测的方式,比如JMeter、nGrinder、Locust等。


业务模块介绍



全链路整体架构

整体架构如下主要是对压测客户端的压测数据染色,全链路中间件识别出染色数据,并将正常数据和压测数据区分开,进行数据隔离,这里主要涉及到mysql数据库,RabbitMQ,Redis,还需要处理因为hystrix线程池不能通过ThreadLocal传递染色表示的问题。



需要应对的问题

业务问题

1. 涉及的系统太多,牵扯的开发人员太多

在压测过程中,做一个全链路的压测一般会涉及到大量的系统,在整个压测过程中,光各个产品的人员协调就是一个比较大的工程,牵扯到太多的产品经理和开发人员,如果公司对全链路压测早期没有足够的重视,那么这个压测工作是非常难开展的。

2. 模拟的测试数据和访问流量不真实

在压测过程中经常会遇到压测后得到的数据不准确的问题,这就使得压测出的数据参考性不强,为什么会产生这样的问题?主要就是因为压测的环境可能和生成环境存在误差、参数存在不一样的地方、测试数据存在不一样的地方这些因素综合起来导致测试结果的不可信。

3. 压测生产数据未隔离,影响生产环境

在全链路压测过程中,压测数据可能会影响到生产环境的真实数据,举个例子,电商系统在生产环境进行全链路压测的时候可能会有很多压测模拟用户去下单,如果不做处理,直接下单的话会导致系统一下子会产生很多废订单,从而影响到库存和生产订单数据,影响到日常的正常运营。

技术问题

探针的性能消

服务调用埋点本身会带来性能损耗,这就需要调用跟踪的低损耗,实际中还会通过配置采样率的方式,选择一部分请求去分析请求路径。在一些高度优化过的服务,即使一点点损耗也会很容易察觉到,而且有可能迫使在线服务的部署团队不得不将跟踪系统关停

代码的侵入性

对于应用的程序员来说,是不需要知道有跟踪系统这回事的。如果一个跟踪系统想生效,就必须需要依赖应用的开发者主动配合,那么这个跟踪系统也太脆弱了,往往由于跟踪系统在应用中植入代码的bug或疏忽导致应用出问题,这样才是无法满足对跟踪系统“无所不在的部署”这个需求。

可扩展性

一个优秀的调用跟踪系统必须支持分布式部署,具备良好的可扩展性。能够支持的组件越多当然越好。或者提供便捷的插件开发API,对于一些没有监控到的组件,应用开发者也可以自行扩展。

数据的分析

数据的分析要快 ,分析的维度尽可能多。跟踪系统能提供足够快的信息反馈,就可以对生产环境下的异常状况做出快速反应。分析的全面,能够避免二次开发。

全链路压测核心技术

1 全链路流量染色

通过压测平台对输出的压力请求打上标识,在订单系统中提取压测标识,确保完整的程序上下文都持有该标识,并且能够穿透微服务以及各种中间件,比如 MQ,hystrix,Fegin等。

2 全链路服务监控

需要能够实时监控服务的运行状况以及分析服务的调用链,我们采用skywalking进行服务监控和压测分析



3 全链路日志隔离

做到日志隔离,防止污染生产日志

当订单系统向磁盘或外设输出日志时,若流量是被标记的压测流量,则将日志隔离输出,避免影响生产日志。

4 全链路风险熔断

流量控制,防止流量超载,导致集群不可用

当订单系统访问会员系统时,通过RPC协议延续压测标识到会员系统,两个系统之间服务通讯将会有白黑名单开关来控制流量流入许可。该方案设计可以一定程度上避免下游系统出现瓶颈或不支持压测所带来的风险,这里可以采用Sentinel来实现风险熔断。

全链路数据隔离

对各种存储服务以及中间件做到数据隔离,方式数据污染

1 数据库隔离

当会员系统访问数据库时,在持久化层同样会根据压测标识进行路由访问压测数据表。数据隔离的手段有多种,比如影子库影子表,或者影子数据,三种方案的仿真度会有一定的差异,他们的对比如下。


.2 消息队列隔离

当我们生产的消息扔到MQ之后,接着让消费者进行消费,这个没有问题,压测的数据不能够直接扔到MQ中的,因为它会被正常的消费者消费到的,要做好数据隔离,方案有队列隔离消息隔离,他们对比如下。



3 Redis 隔离

通过 key 值来区分,压测流量的 key 值加统一后缀,通过改造RedisTemplate来实现key的路由。


框架实现

流量染色方案

上面分析了从整体分析了全链路压测用的的核心技术,下面就来实现第一个流量染色。

1 流量识别

要想压测的流量和数据不影响线上真实的生产数据,就需要线上的集群能识别出压测的流量,只要能识别出压测请求的流量,那么流量触发的读写操作就很好统一去做隔离了。

全链路压测发起的都是Http的请求,只需要要请求头上添加统一的压测请求头。

通过在请求协议中添加压测请求的标识,在不同服务的相互调用时,一路透传下去,这样每一个服务都能识别出压测的请求流量,这样做的好处是与业务完全的解耦,只需要应用框架进行感知,对业务方代码无侵入。



.2 MVC接收数据

客户端传递过来的数据可以通过获取Header的方式获取到,并将其设置进当前的ThreadLocal,交给后面的方法使用。

MVC拦截器实现



Tomcat线程复用问题

tomcat默认使用线程池来管理线程,一个请求过来,如果线程池里面有空闲的线程,那么会在线程池里面取一个线程来处理该请求,一旦该线程当前在处理请求,其他请求就不会被分配到该线程上,直到该请求处理完成。请求处理完成后,会将该线程重新加入线程池,因为是通过线程池复用线程,就会如果线程内部的ThreadLocal没有清除就会出现问题,需要新的请求进来的时候,清除ThreadLocal。

Fegin传递传递染色标识

我们项目的微服务是使用Fegin来实现远程调用的,跨微服务传递染色标识是通过MVC拦截器获取到请求Header的染色标识,并放进ThreadLocal中,然后交给Fegin拦截器在发送请求之前从ThreadLocal中获取到染色标识,并放进Fegin构建请求的Header中,实现微服务之间的火炬传递。




Hystrix传递染色标识

Hystrix穿透

如果使用线程池模式,那么存在一个ThreadLocal变量跨线程传递的问题,即在主线程的ThreadLocal变量,无法在线程池中使用,不过Hystrix内部提供了解决方案。




数据隔离方案

.1 JDBC数据源隔离


通过实现Spring动态数据源 AbstractRoutingDataSource ,通过 ThreadLocal 识别出来压测数据,如果是压测数据就路由到影子库,如果是正常流量则路由到主库,通过流量识别的改造,各个服务都已经能够识别出压测的请求流量了。

2 Redis 数据源隔离

同时通过 ThreadLocal 识别出来压测数据,自定义Redis的主键的序列化方式,如果是压测数据则在主键后面加上后缀,这样就可以通过不同主键将Redis数据进行隔离。

3 RabbitMQ 数据隔离



接口隔离方法

1 Mock 第三方接口

对于第三方数据接口需要进行隔离,比如短信接口,正常的数据需要发送短信,对于压测数据则不能直接调用接口发送短信,并且需要能够识别出来压测数据,并进行MOCK接口调用。



零侵入方案

如果开发的中间件需要各个微服务大量改造,对开发人员来说就是一个灾难,所以这里采用零侵入的springboot starter 来解决

1 自动装配

使用微服务得 @Conditional 来完成配置得自动装配,这里用MVC得配置来演示自动装配,其他得都是类似。 这样可以最大限度的优化代码并提高很高的可扩展性。



2 SpringBoot starter

和自动装配一样,Spring Boot Starter的目的也是简化配置,而Spring Boot Starter解决的是依赖管理配置复杂的问题,有了它,当我需要构建一个Web应用程序时,不必再遍历所有的依赖包,一个一个地添加到项目的依赖管理中,而是只需要一个配置 spring-boot-starter-web 。

服务监控方案

.1 skywalking

Skywalking 是一个APM系统,即应用性能监控系统,为微服务架构和云原生架构系统设计。它通过探针自动收集所需的指标,并进行分布式追踪。通过这些调用链路以及指标,Skywalking APM会感知应用间关系和服务间关系,并进行相应的指标统计。目前支持链路追踪和监控应用组件如下,基本涵盖主流框架和容器,如国产PRC Dubbo和motan等,国际化的spring boot,spring cloud都支持了

SkyWalking是分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8S、Mesos)架构而设计

SkyWalking是观察性分析平台和应用性能管理系统。提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案

SkyWalking组件

  • Skywalking Agent: 采集 tracing (调用链数据)和 metric (指标)信息并上报,上报通过HTTP或者gRPC方式发送数据到Skywalking Collector
  • Skywalking Collector : 链路数据收集器,对agent传过来的 tracing 和 metric 数据进行整合分析通过 Analysis Core 模块处理并落入相关的数据存储中,同时会通过 Query Core 模块进行二次统计和监控告警
  • Storage: Skywalking的存储,支持以 ElasticSearch 、 Mysql 、 TiDB 、 H2 等作为存储介质进行数据存储
  • UI: Web可视化平台,用来展示落地的数据,目前官方采纳了RocketBot作为SkyWalking的 主UI


全链路压测测试

jmeter配置

配置好压测数据,并且配置压测线程数1000 进行10轮压测


Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表