什么是全链路评估
在突发流量场景或者是新业务上线的场景,在未来某个特定的日期或者时间点将会有一轮大流量的用户请求的时候,由于没有真实生产环境运行时候的历史信息做参考,就特别需要通过链路评估来对系统承载能力进行评估,从而保证系统的可靠稳定运行。
我们理解的链路评估,是从访问入口开始,对整条链路的所有潜在的瓶颈点,进行全方位的测量,通过改造链路结构和容量配比,达到提升整体链路性能和可靠性的目的。
这里面的链路评估是相对单系统调优来说的,单系统调优重点关注的是在“机器操作”的微观级别上做具体的软件调整用以挖掘硬件的潜能,单系统调优关注的是单系统的瓶颈,解决的是一个点的问题。而我们说的链路评估,希望解决的是一条线上的问题。
整体链路评估的工作通过对活动目标进行需求分析、设计测试方案、设计指标监控方案,来完成对整个系统的链路测试和优化工作。这四个环节是一个不断循环不断迭代的过程,每当活动目标发生变化,业务场景发生变化,指标的测量结果发生变化,都需要给整个环节带来再平衡。
现在“发红包”已经成为除夕之夜上一道必备菜品,每年的春节除夕,支付宝、qq、微博等都会联合众多行业,每个行业一个品牌,每个品牌一段固定的时间,进行红包派发的活动。社交平台借着派发红包提高了平台人气,各大知名品牌,通过社交平台完成向自己的网站的引流,达到了推广自己产品的目的。在整个活动中,社交平台的网民们拼的是手速,而各大知名品牌为了可靠的推广自己的产品,则拼的是自家网站后台的技术架构。接下来,我们以一个真实案例,来分析一下,红包大促这种的高并发场景的促销活动如何进行链路评估。
红包业务背景
首先介绍一下活动背景,金融行业一个互联网公司,准备在春节除夕,利用与一个大型社交平台合作的机会,进行红包派发活动,并向自己的app引流,吸引更多的用户使用自家的app,在自家的app消费,购买产品。
活动期间,社交平台将会在固定的半个小时时段内,为该公司的app开启专属的红包派送通道,用户可在平台的首页通过刷一刷参与活动。到时候,将有上亿用户,在这半个小时的时间内,通过在平台的首页上不停的刷一刷,进入到我们客户自己的红包页面,参与到3000多万个现金或者是代金券的秒杀活动中。
按照客户的活动预期,现有250万的用户规模,希望借着这次红包活动希望能够吸引到500万以上的新注册用户,也即是说,在抢完红包之后,预计会有250多万的既有用户和500多万的新注册用户,涌入客户的手机app,进行红包的查询和消费操作。
红包的业务规模如下图所示。
在如此的业务规模之下,我们面临两大挑战:
1ï¼ 第一大挑战,3000多万红包,半个小时,一亿以上的用户来抢,而且是整点准时抢,到时候瞬间峰值会非常有考验;
2ï¼ 第二大挑战是,该红包是线上既可以消费,所以抢完红包之后,会紧接着带来线上用户注册和线上消费的峰值,抢红包、登陆注册、线上交易三种高并发写入的场景的峰值重叠在了一起,这更是增加了大促活动线上流量的复杂度;
目标需求分析
了解完活动背景,我们首先进行目标需求分析,目标需求分析包括三部分工作:
首先对业务架构进行梳理,确认整套业务架构都由哪些场景组成,各场景的操作流程是什么样的,哪些是入口场景,哪些是后续的场景,场景之间的交易路径和关联关系是什么?
其次,我们需要对活动目标进行分析,从而预估出每个场景具体的业务峰值。
第三,输出整个系统业务模型,包括所有的场景,及对应的目标峰值。
业务架构梳理
通过和客户的技术人员的调研,我们了解到整体业务架构,包括入口层、服务层、资源层和外部接口层。
入口层指的是发起终端或者调用渠道,该系统的用户的来源是社交平台进行引流,通过手机浏览器在红包系统上抢完红包之后,再下载手机app进行注册登陆并进行一系列消费活动。
服务层提供了具体的应用模块的实现,登陆app之后查询红包列表,然后会选择查询产品列表,查询产品信息,充值,消费红包等等。
资源层则用到了阿里云的rds数据库、redis数据库、oss存储等技术组件。
外部接口包括支付接口、短信网关接口以及红包接口。
将入口层、服务层、资源层、接口层串起来,得出了完整的业务处理流程,从而描绘出了整个业务架构。
业务架构梳理图如下。
业务峰值预估方法
梳理完业务系统,我们需要对整个业务系统的每个场景的峰值进行评估。
对于已上线系统
对于已经上线的系统,我们需要通过该系统的历史大促峰值流量信息对系统的业务规模进行定量的分析,得出大促活动都有哪些场景构成,各场景的占比关系如何,活动目标与入口业务峰值的比例如何。
对于入口业务,也就是说在业务流程上,调用完业务,才可以继续后端的业务流程。需要根据历史日志信息计算出活动目标与业务峰值的比例关系,比如说将具体的活动目标,一般包括在线用户数,新注册用户数,多长时间,达成多大的业务目标,转换成具体的入口业务的峰值目标。
而对于非入口场景,在业务峰值的估算方式上,具体的计算方式可以是考察在历史日志信息中,各个场景占总交量的百分比,进而换算统计这些场景之间的比例关系是怎样的。依据各场景之间的比例转换关系,计算本次大促活动的各场景的峰值。
对于未上线系统
对于没有具体的历史业务信息作为参考的系统,我们同样需要面对两种情况,入口场景和非入口场景。
对于入口场景,我们通用的方式是采用八二原则将活动目标转换成业务峰值。八二原则的定义就是:20%的投入支撑80%的产出。在我们的峰值评估场景里面就是20%的时间支撑了80%的业务量。
对于非入口业务来说,从业务入口进来的流量,在业务不频繁变更的情况下,一定会以一定的比例落到后端的各业务逻辑上。以业务入口峰值作为基准,按照经验值,给出业务入口与后续各业务的比例关系,推算出各业务行为的峰值流量。
业务峰值预估
结合本次具体抢红包业务场景,我们来看下各场景的峰值应该怎么样来预估。在半个小时的活动时间内,我们有三个活动目标,3000万的红包个数、250万的老用户登陆、500万的新增注册用户。对于本次需要评估的系统,抢红包峰值、注册登陆峰值活动都没有历史信息作为依据,所以采用八二原则,根据活动目标预估峰值tps。
非入口的后端的业务链路,参照历史交易信息的比例进行流量转换。考虑到红包场景的特殊性,将某些业务之间的转换率,根据经验,提升到了1:1。
建立业务模型
完成了业务架构的分析,得出了活动涉及到的所有场景;完成了对与活动目标和历史交易信息的分析,我们得出了各场景的业务峰值。于是我们就可以完成业务模型的建立。如表所示,我们看到一共有3个入口业务和10个非入口业务,根据八二原则对3个入口业务的峰值进行了预估,根据历史交易的比例信息,对非入口业务进行了流量的转换。最极端情况下,各种业务峰值重叠在一起,最高峰值tps会达到34.36万
序号 |
场景类型 |
场景名称 |
活动目标或者对应的前端场景 |
峰值tps(万) |
1 |
入口场景 |
抢红包 |
30分钟、3000万+个红包 |
10.7 |
2 |
入口场景 |
老用户登录 |
30分钟、老会员250万+ |
0.8 |
3 |
入口场景 |
新用户注册 |
30分钟、新注册会员500万+ |
1.7 |
4 |
非入口场景 |
短信 |
场景3 |
1.7 |
5 |
非入口场景 |
首页 |
场景1*5/6 |
8.9 |
6 |
非入口场景 |
我的首页 |
场景2+场景3 |
2.5 |
7 |
非入口场景 |
产品列表 |
场景2+场景3 |
2.5 |
8 |
非入口场景 |
产品详情 |
场景7*2/3 |
1.7 |
9 |
非入口场景 |
红包查询 |
场景2+场景3 |
2.5 |
10 |
非入口场景 |
充值 |
场景8*1/5 |
0.34 |
11 |
非入口场景 |
充值回调 |
场景10 |
0.34 |
12 |
非入口场景 |
下单预处理 |
场景10 |
0.34 |
13 |
非入口场景 |
下单 |
场景10 |
0.34 |
测试方案设计
完成了业务模型的建立,接下来我们就需要根据业务模型来完成测试方案的设计这部分我们要做两件事情,第一,选取需要测试的业务场景,第二,选择测试模型
选取业务场景
考虑到尽量模仿真实的用户逻辑,尽量覆盖到所有的业务峰值彼此叠加的场景,尽量能够模拟用户抢红包的整条业务链路,我们选取了服务层所有业务场景。这张图就是所有业务场景混合在一起的整条业务链路。
我们就会对这张图的所有场景进行脚本模拟,但是我们怎么样对这些场景进行测试呢?
选择测试模型
考虑到实际的业务场景目标需求,我们选取了以下四种测试模型。单场景基准测试模型、单场景负载测试模型、混合场景的负载测试模型、系统超时流控测试模型。
单场景基准测试模型,单支交易在系统无压力情况下重复执行多次,检查该交易是否存在性能缺陷,并获取每个交易的基准性能,同时为容量测试提供参考数据。
单交易负载测试,。单交易负载测试模型通过逐步增加并发量进行负载测试,获取单交易业务处理性能峰值,验证单场景是否存在并发性问题。
混合负载测试是按照业务模型的约定在逐渐增加并发情况下进行测试。通过测试,获取模拟实际生产环境中被测系统性能表现数据
系统超时流控测试模型根据对系统中设定流控策略的场景的超时流控功能点有效性、可靠性、稳定性等验证在模拟实际生产系统情况下,验证多个超时流控机制并存情况下的正确性
指标监控
制定好了测试方案,接下来要完成指标监控工作,这样才能在进行压力测试是实施的时候,能够对整条链路进行一个有数据评估。
数据链路梳理
各个业务场景的流量,最终都要量化到数据链路的容量上。
每条数据链路通常包括访问渠道、阿里云的网络产品、应用集群、阿里云的数据库产品、第三方接口等,通常,依赖于链路跟踪功能的系统能够最方便的获取到关联链路的上下文依赖信息,这里由于在这里我们是通过调用地址信息、业务日志的片段信息、连接配置信息来梳理整条数据调用链路,在这里我们选择一个链路较长的业务,抢红包的业务为例:
通过手机浏览器发起操作,数据流量首先经过阿里云的ddos防护产品,然后经过负载均衡设备,到达ecs上的应用集群,对redis和rds的数据写入操作,通过统一的nat网关,完成对接口的调用。整条数据链路是一条同步链路,在对抢红包业务进行链路的能力测量的时候,其中的任何一个环节出现性能问题,都会对整个请求的响应时间造成影响。
确认监控指标和监控方法
对于同一个阿里云产品组件,可能承担了几个场景的访问流量,对于服务组件来说,我们需要重点关注哪些相应的度量指标呢?
对于数据链路上不同类型的技术组件,我们需要重点关注不同的几类指标。
1)前端指标:这也是最能够反映出用户真实体验的指标,我们使用阿里云的pts产品,在压测的过程中能够最直观的关注到tps,响应时间,成功率等指标。如果前端指标符合预期,而后端的数据逻辑也确实跑通的话,我们认为我们的测试符合预期。
2)对于网络接入,网络调度类的技术组件,由于不涉及深入计算及io操作,主要是考量pps、cps、qps、带宽一类的网络技术指标;
比如:高防ip、waf防火墙、slb、nat网关等网络产品都需要重点关注这类指标,在测试评估过程中,在前端指标出现衰减的情况下,首先需要考虑到网络指标是否存在瓶颈。由于业务访问量和这些网络技术指标是可以成正比关系的,如果一旦网络成为第一瓶颈点,我们可以通过网络资源的扩展,有效提高业务支撑能力。
3) 对于部署了应用中间件的ecs集群,我们关注三方面指标,操作系统指标、应用中间件指标和业务指标。应用集群的业务支撑能力取决于三个变量,如果存在后端依赖链路的性能问题,单纯的对应用集群进行规格扩容,对应用进行线程、内存或者计算优化,都无法提升应用集群的整体并发能力。在这里我们通过云监控来关注操作系统的指标,通过开源工具监(Probe、Jconsole
)控应用中间件的指标,通过在日志里埋点,通过日志服务收集日志,并通过云监控订阅日志的方式,来完成业务指标的监控。
(同时在应用集群上,接受请求的tps、处理时间、成功率,对后端调用的tps、响应时间,调用成功率,是反映数据链路健康程度的重要指标,只有这些指标是健康的,能够达到目标的,才能说明前端正常处理的tps请求是可信的。)
4) 数据库类技术组件,涉及深入复杂的计算及io操作,不同的请求会有不同的cpu消耗或者io消耗,所以cpu使用率,qps、内存利用率等都可以通过云监控来关注。另外通过dms数据管理工具,可以对sql会话进行实时的监控。
链路测试和优化
完成了测试方案的制订,监控方案的制定,那么最后一步,就可以通过模拟业务压力,测量整条链路的支撑能力,得出链路的短板,通过容量配比和链路架构优化的手段来达支撑活动目的的最终目的。
根据测试方案的设计,我们的链路测试工作也包括如下四轮。
单场景基准测试、单场景的容量测试、混合场景的容量测试、最后一轮,制定超时流控的方案,并进行验证。
单场景基准测试
单场景基准测试需要达成两个目的。
1) 保证我们选取的13各场景,在系统没有压力的情况下,能够把数据链路跑通,跑通的定义是什么?就是模拟的脚本跑完之后,在压测端能看到成功响应,在应用集群上能看到业务日志,在数据库上能看到写入的信息。
2)我们要获取到每个基准测试的响应时间,根据基准的性能,我们需要让业务人员评估出一个在用户看来能够接受的响应体验,
根据 并发用户数=峰值tps*响应时间 这个公式,我们能够了解到,在这个保守的响应体验的基础上,要想达到场景峰值,需要多少并发用户数。为接下来的单场景的容量测试,提供并发用户数的依据。
序号 |
业务类型 |
场景名称 |
活动目标或者对应的前端场景 |
峰值tps(万) |
响应时间(s) |
并发用户数(万) |
1 |
入口场景 |
抢红包 |
30分钟、3000万+个红包 |
10.7 |
0.25 |
2.675 |
2 |
入口场景 |
老用户登录 |
30分钟、老会员250万+ |
0.8 |
0.25 |
0.2 |
3 |
入口场景 |
新用户注册 |
30分钟、新注册会员500万+ |
1.7 |
0.25 |
0.425 |
4 |
非入口场景 |
短信 |
场景3 |
1.7 |
0.25 |
0.425 |
5 |
非入口场景 |
首页 |
场景1*5/6 |
8.9 |
0.2 |
1.78 |
6 |
非入口场景 |
我的首页 |
场景2+场景3 |
2.5 |
0.2 |
0.5 |
7 |
非入口场景 |
产品列表 |
场景2+场景3 |
2.5 |
0.2 |
0.5 |
8 |
非入口场景 |
产品详情 |
场景7*2/3 |
1.7 |
0.2 |
0.34 |
9 |
非入口场景 |
红包查询 |
场景2+场景3 |
2.5 |
0.2 |
0.5 |
10 |
非入口场景 |
充值 |
场景8*1/5 |
0.34 |
0.4 |
0.136 |
11 |
非入口场景 |
充值回调 |
场景10 |
0.34 |
0.4 |
0.136 |
12 |
非入口场景 |
下单预处理 |
场景10 |
0.34 |
0.4 |
0.136 |
13 |
非入口场景 |
下单 |
场景10 |
0.34 |
0.4 |
0.136 |
单场景容量测试
在链路测试的第二个阶段,我们需要对每个场景进行并发数递增的施压过程,直到tps达到也场景峰值的需要。
由于这一步是容量测试,也就是说链路上并发能力的问题开始暴露出来。
数据缓存热点问题
我们发现在抢红包的场景和新用户注册的场景出现了大量的调用超时。
通过云监控查看Ecs所组成的应用集群的资源占用率不高,redis的调用qps也没有达到redis集群的极限,而从业务日志监控上来看对于redis的调用却出现了大量超时。
我们分析了一下具体的业务场景:
redis在这套架构中主要是充当缓存和计数器使用。
我们采用集群模式的redis提供服务,集群模式的redis,后端采用多分片的架构,扩展能力极强,而且可以破除单机redis单线程机制的性能瓶颈。
对于redis多分片的集群,key比较分散的场景可以对资源进行充分的利用。
而在发红包和注册的计数器应用上,两个计数器应用,分别是两个key,却承担了高并发场景所带来的高并发操作,而一个key的所有qps操作却分别只能hash到一个分片上,于是这个计数器的qps和其他场景将这个分片上的能力迅速撑爆。
我们对客户提出了将热点key进行隔离的建议,
1、注册峰值和红包峰值的热点key使用独立的redis实例;
2、在redis集群上对热点key进行单独的集群分片路由;
在优化之后的在此容量测试中,得到了预期的场景峰值。
高并发写入延迟问题
架构设计:
应用集群采用了基于dubbo的服务化设计,交易中心和注册登陆中心,分别负责产品下单信息的入库和注册信息的入库。
现象:
我们在进行单场景容量测试的时候,发现抢注册场景、产品下单信息入库的两个场景的响应时间都特别长。
而这个场景对应的集群的业务日志监控发现,数据库的写入时间非常长。而且短信网关的也已经开始调用超时;
场景分析:
1、消费信息峰值、用户注册峰值、短信入库峰值对于数据库的写入造成了较大的压力;
2、短信验证码的峰值超过了短信通道的峰值能力
扩展方式
我们通过消息队列来控制对后端数据库和网关的调用频率,尽量降低对后端的高并发压力,同时也快速响应了前端用户。
混合场景容量测试
对各个场景分别进行了容量测试,我们从各个单场景的角度进行了链路的优化,那么这些单场景叠加在一起,能否分别达到各自场景的容量峰值呢?
网络容量问题:
我们按照实际的业务链路的先后顺序,依次对各场景进行并发压力增加的操作。当压力增长到一定值之后,我们发现,前端指标中,响应时间和tps指标衰减变得非常严重,而数据链路中,应用集群,数据库上面的指标几乎没有增长。
场景分析:
我们的网络接入场景非常简单如图所示,采用通过高防ip来进行ddos和cc攻击的防护,通过slb来实现七层负载均衡的调度。
优化方式:
按照从前往后的顺序排查瓶颈点,首先,我们发现高防ip的回源带宽指标达到了瓶颈,首先对高防ip进行了多实例的扩展;
接下来,我们发现所购买的slb实例已经达到了规格上限,带宽指标和pps指标已经达到了极限,然后我们又对slb实例进行了多实例的扩展;
由于红包大促平台要求,各商家要统一使用https接入,对原来的http请求全部进行了https改造,我们也继续通过slb实例的扩展来抵消掉改造成https所带来的性能的衰减。
结果:网络接入是所有业务场景的入口,在确保了网络接入流量不成为瓶颈之后,后续的容量测试过程中,请求流量顺利的从这里进入应用系统、缓存、消息队列、数据库中。
超时流控测试
由于第三方接口的容量不能随着我们调用方的峰值要求,进行扩展,甚至还会在高并发场景下进行限流,所以在链路测试的最后一个阶段,我们要设计好应对流控超时场景下的方案,并进行验证。
架构设计:通nat网关可以充当一个高可用的SNAT设备,同时能够使用一个固定的ip池,能够满足第三方接口对于白名单的需求,所以全站对外部接口的调用的需求,统一使用NAT网关产品。针对于每个虚拟机交换机下的ECS资源池,可以购买不同规格的的NAT网关的带宽来满足不同虚拟交换机下的应用集群的对外调用网络容量需求。
场景描述:
降级流控策略的设计和验证:
1)在对于短信网关的调用上,虽然我们采用了异步化的方式,大大降低了对于短信网关的并发调用量,但是短信网关调用对应的业务场景是注册验证码,但注册验证码是有时间限制,对于时间存在一定的敏感度。于是我们建议客户对于异步化对外接口的调用,通过消息队列的积压度来进行降级流控策略,当队列积压度达到一定的数量,返回运营页面,减缓一下用户的注册频率。
2)对于支付接口的调用的调用上,为了避免线程堆积对应用集群带来的雪崩,我们采用的降级流控策略是降低超时时间和重试次数,为了在外部接口不可用的时候,快速通过友好的界面将失败返回。
链路测试实施:
在实际测试的时候,我们将所有场景保持在了一定的水位上,对支付和注册的场景进行了压力递增的测试。通过限制支付场景对外调用的NAT网关的流量,我们成功验证了在高压力下支付接口调用超时的流控策略;通过暂停掉注册场景的队列消费进程,我们也成功验证了在队列积压度达到一定比率的时候,注册场景的降级策略。
最终架构设计
几轮压力测试下来,我们对每条链路上的架构进行了重新的评估。得出了最终的系统架构。
从应用分层的横向的纬度,这各架构分了四层结构。第一层是网络层,管理网络流量的进出,第二层是应用层,第三层通过redis实现了数据缓存,通过阿里云消息中间件实现了高并发调用或者写入的异步化处理,第四层是数据库和文件存储层。
从系统纵向切分的角度,从网络层上,CDN提供静态服务,实现了对接入流量的负载均衡,NAT网关实现了对外部接口的统一调用。从应用垂直拆分的角度,通过使用dubbo框架,将不同的业务(或者数据库)切分到不同的服务器(或者数据库)之上,将动态静态业务也进行了拆分,拆分到了不同的应用集群上,进行垂直扩展,将不同的功能和服务分割开来,便于不同模块的分布式部署。在缓存层面,不同的业务,也可以使用独立的缓存实例,对热点业务进行隔离,在数据存储层面,数据库随着业务的拆分,同样进行纵向拆分。
在分布式扩展上面:将分层和分割的应用和服务模块或者是阿里云的技术组件进行分布式扩展,以便获取更大的支撑能力。
总结
通过链路评估的工作,我们支持客户做了两个活动预案:一个是扩容预案,一个是降级预案和降级之后运营页面的准备;
1)在整点活动前2个小时完成了对活动系统的扩容准备工作,可以说把钱用到了刀刃上,这么短的成本周期,只有在公共云上才能实现。
2)在活动当晚,所使用的第三方支付平台恰好与别的商家活动发生了重叠,导致支付接口出现了一些波动,我们提前准备的快速失败的降级策略,避免了线程的堆积,而且返回给了用户一个比访问超时较好的体验;
活动期间参与红包活动的用户高达2亿+,成功派发数亿现金及卡券红包
支撑了业内第一的日用户注册及充值交易转化率。客户非常满意。
活动峰值持续了5分钟,活动高峰整整持续了半个小时,在此期间,整个的系统的业务指标表现的非常稳定,外部接口的不可靠也通过降级预案进行了完美的控制。链路评估的工作成果也体现在了结果上。