vlambda博客
学习文章列表

揭开云集全链路压测的神秘面纱


一、背景

自2015年5月上线以来,云集连续几年爆发式增长,云集业务迅猛发展的同时,技术平台的服务系统也经历了爆发式增长;服务与服务之间的依赖调用越来越多,越来越深,用户下单经过的服务多达几十个。在以往的大促准备期间,按照大促的目标流量值有哪些服务需要扩容,扩多少?哪些服务存在瓶颈无法通过扩容解决?核心交易流程真实能承载多少的流量?这几个问题没人能准确回答。

虽然云集已经有了各种各样的监控、应急降级预案、调用链跟踪、日常TOP压测、引流压测、生产写压测、容量评估、各种限流、业务主流程监控等技术工具和保障手段;但核心交易流程在大促流量高峰期间,总是会出现各种各样的问题,影响用户的购买体验。为了保证大促的期间系统的平稳运行,业务架构师牵头组织:DBA、业务开发Leader、运维、测试、基础架构等部门人员开展大促

稳定保障的前置工作:

  • 收集以往大促期间的出现问题

  • 综合过往表现和大促目标可能面临的瓶颈

  • 梳理现有业务,了解清楚大促期间可能涉及到的业务场景,将核心和非核心业务区分开

根据大家的反馈和梳理,很快知道几个重要的性能瓶颈点:订单依赖主从库和redis存储、订单部分业务依赖单库、用户依赖单库、商品服务负载过高且无法通过扩容解决。业务架构师团队迅速主导订单、商品、用户的重构和优化,并利用重构加深对业务系统的理解。同时还了解到云集和传统电商有很大的差别是 S2B2C,大促期间销售量大的商品对应的链路在日常可能完全没有流量,这是上面各种手段保障下大促依然失手的主要原因。

二、目标

了解到主要问题点后,团队接下来准备要做的和大家想法是一样的:如果可以将压测做到复现双11的流量,将压测当大促来做,那么双11核心交易流程链路的稳定性保障就有信心了。基于自身的业务特性云集大促无法采用流量录制重放的方式,来完全模拟真实流量进行仿真压测,因此需要结合梳理的业务场景进行压测。目标:大促期间"双11核心交易流程链路"零性能故障。

三、场景化压测

云集将压测分为以下几个步骤进行:1)业务梳理  2)环境准备 3)数据准备 4)压测预演  5)场景化压测  6)问题定位与解决  7)回归压测  8)大促预演

1)业务梳理

业务梳理阶段主要是区分核心与非核心业务,将工作的重心聚焦,同时避免场景遗漏。除了和业务研发负责同学沟通业务,还有其他几种方式可以协助分析业务:重构(最有效,但最耗时)、抓包(最快的方式,但可能存在遗漏,需要很资深的对业务非常了解的测试,尝试各种业务组合条件进行抓包分析)、走读前后端代码理清相互调用关系、分析调用链拓扑图(目前云集调用链拓扑图还需要完善)。

通过以上几种手段,将梳理出来的业务按场景重新组合:用户登陆、导购(包含首页、频道/专题/列表、商详)、下单线(包含购物车、确认订单、提交订单)、支付(包含收银台、支付完成)、我的(包含个人中心首页、订单列表、订单详情页)列为"双11核心交易流程链路"。还有一个很重要的组合场景:top1~200。

揭开云集全链路压测的神秘面纱

如上图所示,确保用户从登陆、查看商品、添加购物车、结算、支付、订单查看整条核心交易流程。

2)环境准备

性能压测需要针对系统稳定性、系统瓶颈、核心业务逻辑进行地毯式覆盖压测;为了方便压测,需要考虑如下几种需求:

  • 大流量、全方位、低延迟  对整个系统进行压测,并模拟大促时的流量,其规模是海量

  • 丰富压测场景  支持 Http/Dubbo 接口两种协议的压测支持。并且针对业务场景对多个压测链路进行聚合分组,作为场景进行压测,能够对同一场景下的链路进行单独的压测并发设置,权重设置等。

  • 自动构建压测数据  在压测的同时,为了方便压测人员,希望压测工具能够提供自动的请求数据获取,这些数据可以来自生产线上的真实数据,而且需要考虑对敏感数据进行脱敏处理。

  • 压测报告、实时趋势  在每一轮压测结束之后,需要有一个详尽的压测报告出来,并且能够有一份实时压测统计图

为了尽可能真实的模拟出大促时核心交易系统的峰值表现,在平衡成本和效果之后最终选择在生产环境进行流量打标的方式进行场景链路压测;云集使用自研的 titan军演系统 结合自定义复杂流程压测工具来模拟各种订单的复合场景

揭开云集全链路压测的神秘面纱

Titan简单介绍

Titan 是一款分布式的压测工具,支持HTTPDUBBO 接口的压测,支持构建链路,场景管理,自动压测,参数自动获取等丰富的功能。

  • Manager Web:前端展示组件,整个压测的所有交互性的操作(例如 链路创建、场景创建、执行压测等)都在上面完成。并且Manager直接通知 Commander

  • Commander:负责接收来自Manager的压测请求,并将压测请求根据策略发送给所有的Agent,并启动每一个Agent执行压测

  • Agent:直接进行压测的组件,负责压测并分别生成报告,与Commander直接通信

  • CiaAgent:负责收集Nginx日志,并过滤链路和请求参数,脱敏处理,存储请求参数

Titan特点

单机压测性能高,Titan-Agent的Http压测Client采用的是AHC(Async Http Client),这是一款基于netty的高性能、异步化、基于Reactive模式的Http客户端。经测试,对逻辑复杂度小的业务压测其QPS能够达到10w/s以上的水平。

一键动态扩容缩容,Titan-Agent可以进行动态的扩容,从1台、10台、100台到1000台,集群理论上可以支持到万台的级别,这样一来,每台agent分工,对压测需要的海量、洪峰流量就能够进行模拟和压测了。

Titan影子压测实现方式

业务代码里面如果存在版本冲突,可能会导致标识无法向下传递;所以在压测环境准备的时候,需要通过调用链分析确保每个链路影子标识传递正确

对于无法进行标识传递的一些系统和外部接口,需要将对应的消息禁用消费和接口挡板处理

ThreadLocal建议大家采用 TransmittableThreadLocal( Alibaba开源的、用于解决 “在使用线程池等会缓存线程的组件情况下传递ThreadLocal” 问题的 InheritableThreadLocal 扩展)

揭开云集全链路压测的神秘面纱
image.png

3)数据准备

数据准备的前提

压测的内容与范围 :每次压测前,需要列出压测计划及涉及到的接口,并整理出影响的数据库、消息、缓存,这样方便DBA有针对性的关注服务器的资源情况

提前评估压测服务器的资源情况 :DBA需要关注服务器资源(CPU,IO,内存等),现有生产数据的容量,服务器近一段时间的压力情况等,结合业务数据,从而评估在压测期间服务器是否需要扩容等

需要关注的方面  :DBA需要关注在不同的QPS下,服务器的CPU,内存,磁盘IO,网络IO等表现出来的数据,做好总结。归纳出不同的服务器资源所能承载的QPS的最大值,以给业务方做好充足的性能评估

压测的指标 :每次压测前,业务方需要根据运营的需要大致计算出压测所要达到的效果,峰值QPS,接口调用的最大频率,响应时间等。

数据准备的分类

初始数据构造:通过工具复制大促业务涉及的系统影子库、消息、缓存,好处是可以模拟数据量,更真实的反应系统在同等甚至更多数据量的情况下的性能表现,摸出真实水位。链路压测需要经历的时间比较长、涉及的系统非常多,这期间不可避免的会有发版,需要DBA在发生DDL变更的时候同步到影子库。同步schema的过程,可以用开源工具:mysql-schema-sync-master。对于缓存,业务研发需要提供接口可以在压测的时候,重新刷新缓存数据

基础数据构造:构造场景模拟需要的基础数据:用户、活动、商品、库存、运费、规格、毛重、余额、云币、优惠券等等;主要有几个考虑点:复制生产的真实数据将手机、实名信息、密码等敏感信息脱敏,将用户ID和生产完全隔离开以免影子标识丢失影响生产用户

场景数据构造:分大促预演模型和场景化数据模型。为了尽可能真实模拟,我们需要将大促时的业务进行建模,根据建模配置详细的链路。每一条链路的数据构造涉及到的用户、商品、活动需要打散避免热点数据影响压测结果,用户资产也需要模拟大促时的情况,比如大促时可能会给每个用户发放很多优惠券。在进行场景配置的时候,需要根据业务的实际情况,指定不同链路的流量权重比例。首页->商详→购物车→订单→支付应该是一个逐步递减的漏斗模型。

1)  日常生产请求流量:通过云集 Titan 系统的CiaAgent 来订阅 Nginx 的日志收集,然后发送到 Kafka集群,并按一定比率的丢弃策略去分析 Nginx 请求日志,过滤出前端请求 url 和请求参数等等信息。抓取到的链路的请求数据来自于真实线上,这块需要对一些用户私人敏感信息做脱敏处理,然后将处理好的数据存入时序数据库 Influxdb 中。

2)  特殊情况:云集一个特例就是电商的预售业务,分订金和尾款两步,平时完全没有此业务流量,需要单独考虑数据模型

链路图:

揭开云集全链路压测的神秘面纱

场景图:

揭开云集全链路压测的神秘面纱

4)压测预演

压测预演,是对压测环境构建的结果验收,因为全链路压测涉及到几百个系统,不可避免的出现数据库、缓存、topic漏准备的情况;如果是第一次进行链路压测,最好是将压测预演和数据准备同步进行,避免因为某些系统没有搞好影子配置或版本冲突的情况,影响计划推进。在预演阶段,我们主要碰到几个问题:下游系统没有配好依赖的数据或缓存,版本冲突导致影子标识丢失,系统发版数据库出现影子数据库没有对应字段,活动配置时间不对,刷新缓存脚本不起作用,依赖的底层系统没有影子库功能,防火墙配置不对,DNS配置不对等。

5)场景化压测

在此阶段,主要是根据大促目标构造真实流量,对目标链路进行摸高压测探测系统水位,一直摸高到出现系统问题为止。为了确保系统能够撑住大促峰值,目标链路涉及到的上下游需要撑住比大促预估峰值更高的流量,比如大促预估峰值*2。在开始场景化压测之前,需要做以下几个准备工作:

放开一切流控手段,不然全部流量被挡在系统外部,在云集存在几种流控手段:nginx限流,diamond限流,sentinel限流

提前预估用户、商品、库存的缓存容量,避免因为影子缓存数据过多而踢出真实生产的缓存数据的情况发生

系统预热,对于活动、商品、毛重、规则、商详信息、图片等需要提前预热

预售尾款需要提前准备好可以进行尾款支付的订金订单

根据以往的大促的峰值表现,提前扩容好应用服务器、nginx机器、云上的资源要提前和运维沟通好确保资源的空闲避免共用的情况、waf/clb必要的情况下采用独立集群部署

正式开始压测,需要选择不同的压测策略来模拟不同的流量表现:固定流量、平稳流量、尖峰流量;进行场景化压测的时候,当压出某个系统的问题时,如果可以快速判断问题点并花很少时间解决,可以再次进行压测。不过我的建议还是尽可能多的压到准备好的场景,因为这样可以在最短的时间内发现全链路关联系统的水位及问题点,然后给出充足的时间让对应系统的研发同学解决问题并发版处理。

6)问题定位与解决

在场景化压测的时候不可避免的会发现这样那样的问题,需要用到各种各样的工具或命令来协助分析,这里推荐网络上可以获得的且大家常用的:

  • Arthas 可以在压测出现瓶颈的时候,进行trace、watch等查看方法耗时和函数出参入参

  • Jprofiler、Async-profiler+FlameGraph 、eclipseMAT 非常好用且功能强大的Java开发分析工具,它可以快速的帮助分析出系统运行的瓶颈点

  • SkyWalking 一款优秀的国产 APM 工具,包括了分布式追踪、性能指标分析、应用和服务依赖分析等

  • Grafana是一个跨平台的开源的度量分析和可视化工具,可以通过将采集的数据查询然后可视化的展示,并及时通知

必要的时候,你可以能还需要用tcpdump命令,进行网络分析

  • 常用命令工具:tail、grep、awk、top、netstat、btrace、greys(arthas基于这个)、javOSize(在线改代码啊)、jstack、jmap、dump、jstat、jdb、dmesg

这里介绍一下云集自研的链路追踪系统 Erlang,链路追踪技术主要是收集、存储、分析分布式系统中的调用事件数据,协助开发运营人员进行故障诊断、容量预估、性能瓶颈定位以及调用链路梳理;全链路压测的影子标识也是需要通过它来传递的。通过erlang可以去查看一些链路耗时不正常的链路,可以观察在一个http请求的链路上,在接入层表现耗时高的情况下,需要结合erlang来进一步分析是在哪个接口导致了耗时高,或者是mysql、redis等的耗时高,等定位到这一个点之后需要更进一步去结合mysql、redis的client server的日志和监控数据做进一步的分析

Erlang链路例子截图:

揭开云集全链路压测的神秘面纱

7)回归压测

除了场景化压测过程中发现的问题的场景,需要回归压测验证之外,还有另外一种情况需要考虑:在压测的过程中,可能有些系统经历过发版,新上线的功能可能会影响压测的结论。在大促封板日期封板之后,对上线的项目进行review并再次抓包,将遗漏的链路补充之后回归压测。回归压测看起来繁杂,但其实如果系统不存在问题,每次的场景压测花不了多少时间。网上已经有比较多的同行已经开始了自动化实践,云集也在做这方面的工作。

8)大促预演

大促前几天,会根据压测结果结合以往的峰值表现,进行生产的扩容。扩容完成之后,需要调整各个系统的连接池设置、限流值设置。保险起见,在大促最后一晚进行大促预演,此时的模拟是最真实的:一样的限流配置、一样的连接池配置、一样的机器部署。主要目的:检查各项配置是否准确,监控是否完备,限流是否设置。

四、总结

2019年双11云集的大促压测,历时几个月的持续压测与优化,由业务架构师、DBA、运维、测试、开发、架构组成支持大促压测的团队,最终系统经历大促的流量冲刷保持稳定顺利度过双11。

大促是检验系统的最有效手段,经历大促流量的洗礼安稳度过曾经提心吊胆的日夜,是对每一位参与大促准备工作的研发同学最好的奖励。尽管如此,我们依然敬畏,因为我们无法做到在大促的时候淡定喝茶聊天。也许有一天,云集的自动化全链路压测之路走起来之后,会有这个可能。




          关注一下,更多精彩等着你!