无相:2014年加入蘑菇街的搜索团队,开发了类似于全链路监控的工具,用于提升整条链路的稳定性。后开始负责全站稳定性工具和平台相关的工作,并参与了全流程加速系统的开发。


蘑菇街是一个电商平台,每年会做四次大促,3.21、6.18、双11、双12。大促保障涉及到流量评估、依赖梳理、单链路压测、全链路压测等。蘑菇街大促的基本流程,基本是按照系统峰值评估、依赖关系梳理、单链路压测、系统扩容、全链路压测等几个环节展开的。


在保障大促稳定性工作的时候,稳定性团队会有一个KPI:这次大促不能出某个级别以上的故障,如果出了这个级别以上的故障这个KPI就挂掉了。第一次接到稳定性工作,我也是很迷茫——很多事情是其他团队小伙伴做的事情,万一他们的疏忽出了一个故障,这个也要我一起背吗?后来逐渐摸索出一套应对大促带来大流量,行之有效的大促稳定性保障方案。


Clipboard Image.png

评估系统峰值

机器和成本总是有限的,因此在每次大促之前必须要估出一个合理的峰值,根据峰值合理地扩容。每次大促开始前,必须找到运营方沟通大促的业务目标:大促GMV,包括预估的PV、UV、客单价、转化率。根据运营给出的数据,推算出所有系统的峰值,其中重要的是下单系统的峰值。

倒金字塔梳理系统峰值

下单峰值的评估,有点像我们做应用题一样。已知运营给出大促的目标,包括PV、UV、GMV,要求推算出下单交易系统峰值。这里分享一个经验公式,“预估大促GMV/历史大促GMV×历史客单价/预估客单价”,一般就等于历史大促峰值。通过这个可以算出这次下单大概峰值是多少。


Clipboard Image.png


算出了下单峰值之后,再套入一个倒金字塔的模型。电商场景都是有一定特点的:

前面流量会从会场、首页、外部分享页进来,然后进店铺页面、图墙页面、搜索页面。到了这些页面之后会进入详情页;到了这里用户可以加入购物车,做购物车的操作;然后就可以下单、支付了。浏览了详情页后,有多少人基本会下单,这个比例我们称之为“转化率”,转化率可以预估出来了。


Clipboard Image.png


根据一定的比例关系,一旦确定好下单数额之后,就可以倒推出每个系统在本次大促是要承担多少QPS,把每个系统的峰值算出来。推算出每个系统QBS之后,再根据以往经验进行对比,比如对比3.21大促的预估峰值跟实际峰值,假如当时估值偏低,那在下次大促时稍微调高一点,这样就会确定本次大促各自系统峰值是多少。

关注运营玩法和架构的变化

电商平台的运营玩法层出不穷,一定要关注运营玩法和架构上的新变动,这对预估峰值来说很重要!蘑菇街吃过这方面的亏。


比如今年3.21大促的时候,运营在晚上10点时候会上线有一波游戏,App会有信息推送,首页会会弹出直达这个游戏的提示框,有好几种方法可以把流量迅速导到游戏会场去。在游戏开始之前我们没有太关注这个游戏的玩法,只是按照以往的经验简单估了一下这个值。但是游戏的流量比预估值高上一倍!那次大促有一半的KBS直接被限掉了,这对客户体验非常不好。


后来总结经验,对于这些玩法的变动,一定要做大促稳定性保障,一定要了解的细致,不能只是很泛泛地去问一下:玩法有没有新变动?是不是跟以前一样的?要具体到运营的每一个步骤,不问清楚很有可能对流量预估产生影响。


架构上有新变动带来的影响更不要说了,比如你以前应用是部署在物理机上的,现在部署在虚拟机上了;或者之前用A中间件,现在用是B中间件。架构上的变动一定要重点关注。

梳理依赖关系

一旦业务变大或服务化细致之后,依赖关系会变得非常复杂,梳理起来很麻烦。有时候某一个应用挂了,可能是某一个依赖方挂了;你负责的应用挂了之后又会导致所有调用此应用的应用也挂了。


在全链路监控系统上线之前,做依赖关系的梳理其实是一个非常麻烦的事情,假如开发人员出现了流动,新人接手这个系统,只有看代码才能知道依赖关系,对代码不太熟悉的话还会出现漏判的情况。有些代码因为业务逻辑关系非常复杂,很难判断和梳理,用比例无法精确计算。


依赖关系不明确,万一带大促的时候这个依赖发生了状况,但没有做预案处理,可能对系统本身的稳定性会产生影响。


Clipboard Image.png


现在蘑菇街是通过全链路监控系统来梳理依赖关系,因为全链路监控系统可以知道一条链路下来的每次调用,通过计算可以知道调用者和被调用者之间的调用比例关系,甚至可以详细到接口。


通过全链路监控系统梳理出来的全站应用拓扑,前端的应用是Web Trode Order,调用了很多的应用。只要把这个关系出来就一目了然,再也不用看代码,而且直接知道它们之间的关系。


系统压测和扩容

蘑菇街的步骤是,先做单链路压测,再做扩容,后做全链路压测。


在没有统一的全链路压测平台之前,业务方都是自己组织压力测试的,各种各样的压测工具都有。这里有几个注意点,一个是当你需要压到很高的QPS的时候,本身有限制,QPS不是很稳定。另外如果压测数值很高,业务方手里没有机器,他要跑到PE去申请,PE一般也不会给机器,这怎么办?基于这个问题,蘑菇街开发了全链路压测平台,把机器当成一种资源:只要告诉链路定义、场景定义和任务定义,简单定义之后就可以压测了。


单链路压测

在单链路压测阶段,各业务方把各自需求应用全部做完100%流量的压测,并且要验证所有的流量、限流策略是否正确。


单链路压测的时候有一个“局部集中”的概念,在做单链路压测的时候,电商基础相关的业务压测要尽量放在一起压,比如详情、促销、优惠、交易、下单,之前都是各自压测,但这些应用互相都是有交互情况的,尽量在同一天单链路压测的时候就一起进行调。如果有问题可以提前发现解决掉,而不会把这些问题推到全链路压测的时候去解决。


系统扩容靠单机压测

单链路压测完了之后就开始做系统扩容。蘑菇街做系统扩容,必须要由单机压测系统提供水位报告,有数据说话,拒绝拍脑袋,才能够减少机器、降低成本。


比如有些应用压测出来要扛5千QPS,但是我只能抗3千,这就需要找PE扩容机器。扩容要尽量节约成本。业务方为了自己的应用更安全一点,通常会多要几台机器,能扛多一点,心里安全一点。如果对每一个业务方都心慈手软的话,你就放出去太多机器了,成本没法控制,必须要求业务方要拿着单机水位压测包来扩容,不能拍脑袋说“再给我5台机器,让我更安全一点”。


为此蘑菇街做了单机压测系统,它有两种方法,一种可以把线上真实流量全部会聚到其中某一台机器上去,这样可以测这台机器的真实水位到底是多少。另外一种情况,可以利用全链路压测平台,打模拟流量到一台机器上去,这样也可以测出这台机器真实水位是多少。


打流量的时候也不是一次打,假如你预测这台机器单机水位大概能达到1千KPS,我可能从100开始打,100打完了打200,直到测出你这个系统单机水位。这里的判断标准和预值通常是让业务方自己测,比如他测试CUO到了一定值之后,比如到了80%,就可以认为到极限了。业务方完成单机压测后,方可拿到机器进行扩容。


全链路压测要尽量真实

扩容之后要进行全链路压测。各自做单链路压测是不行的,因为在所有流量会聚到一起的时候,对整个系统某些平行点可能会发生意想不到的情况。所以在单链路压测做完之后,一定要把所有系统会聚在一起做全链路压测,一般会做两到三次。


一般认为全链路压测知道压过就OK,其实不是,全链路压测都够了,后来大促发现了问题,问题在哪里呢?因为全链路压测是模拟流量,平日的真实流量没有到大促那一天这么大,没有那么多的数据用于模拟流量数据库;比如线上商品有10万,业务方为了简单化,后来在测试数据库里只有2万的商品,所以在做全链路压测的时候没有发现这个问题,测试时的网卡流量虽然比较大,但是没有把网卡打爆。但是在真正大促当天,10万商品的流量一下子下来之后,就把网卡打爆了。


进行反思后,蘑菇街要求全链路压测数据要尽量真实,尽量模拟现场的情况。但是全链路压测的成本也要考虑好,这之间的度要把握好。


Clipboard Image.png


全链路压测是一个苦活,通常在晚上12点之后,持续四到五个小时,一直到凌晨。这里要提高人效、降低成本,蘑菇街尽量减少晚上压测的成本,如果白天压测50%的量,晚上可以从75%开始压了,这样就可以节约了晚上的压测时间,就不用到凌晨4点、5点,一般凌晨2点就可以手工了。


2017年蘑菇街也在想一些办法,可不可以在白天也做一些全链路压缩;白天做全链路压测的方向是有的,就是隔离出两个动态环境,一部分环境是线上流量,另一部分环境专门用于压测,这样互相不影响。这个方案还在可行性验证当中。


以上工作准备充分以后,还要准备一份预案评审和作战手册。


预案是为了大促如果真发生了事情到底怎么办,包括前面做依赖梳理的时候,一个系统如果有三个依赖的话,需要对每个依赖都要做好一个预案:这个依赖如果挂了怎么办,降级还是别的处理方案?


作战手册就比较简单明了,出现什么问题,团队成员能够在作战手册里第一时间找到应对方案和措施,及时应对,解决突发情况。