电商大促准备流程v2
1 概述
对于电商企业而言,每年都会有几次大的促销活动,像双十一、店庆等,对于第一次参加这个活动的新手,难免会有些没有头绪,因而将自己参加双十一、双十二活动中的过程心得进行下总结,一方面供以后工作中继续使用,另一方面也供大家参考。
2 主链路梳理
当前主流的IT架构基本上都是SOA的架构,一个业务的完成需要多个系统的参与,这些参与的系统便形成一个链路。而主链路就是双十一、店庆中必须参加的、无法进行降级的业务,对整个系统而言通常的像登录、商品浏览、下单、支付等都是主链路。具体到自己负责的系统,就需要和自己的上游系统进行沟通,以确定自己的那个服务参与到了那个主链路中,如果自己的服务还需要调用下游的系统,也要和下游系统进行沟通,以确认其系统是否有足够的能力的支持。同时还需要考虑自己服务中对db、缓存的读写需求。最终形成若干个主链路调用图(如下示例)。
3 确定主链路的tps/qps峰值
在确定自己参与的主链路之后,就需要和上游系统确定各链路的tps/qps。通常来说一个系统能支撑的tps要比qps低,因为写操作通常是排他锁,而读操作是不排他的。在确定各链路的tps/qps后,进而确定其对相关资源的 tps/qps。在确定完各链路对相关资源的tps/qps后,对于相同的资源进行汇总,最后形成一个总的资源需求,提供给关联方(如DBA、pe、系统owner)以进行评估。
编号 |
类别 |
表名/接口/集群 |
tps峰值 |
qps峰值 |
1 |
hbase |
device_index |
4w |
6w |
2 |
mysql |
device_app |
2.5w |
10w |
3 |
缓存 |
public |
7w |
10w |
4 |
下游系统 |
getIdByToken |
0 |
2w |
在常用的业务实现中,会在db前面使用缓存,因而在评估db的qps时要考虑缓存命中率的问题,比如日常的缓存命中率为70%,也就是100个查询请求,只有30个到达db。但在评估峰值调用时,不能按照日常的缓存命中率来判断有多少请求到达db,因为在大促期间会有一些平时不活跃的用户的过来,因而大促期间的缓存命中率要低于日常的缓存命中率。但具体低多少,这个很难有一个公式来判断。这个和大促期间的活动有一定的关系,如果有预热过程并且缓存空间足够的情况下,大促和日常的缓存命中率相差不大;如果是没有预热的,并且缓存空间有限制,就需要根据情况适当的降低些缓存命中率计算db的qps。
4 压测改造及压测联调
在确定好对应的qps/tps后,就需要进行压测,看下系统最大能支撑多大的量。首先应该能够判断出一个请求是正常的业务请求还是压测请求,不同的公司有不同的压测判断方法,对于tps的压测,可能还需要创建影子表,比避免压测数据“污染“线上真实的数据,如果过来的请求是压测请求,在进行db写操作时,应该选择影子表而不是线上生产环境的正式表,这个应该有一个统一的框架或组件来完成。在代码实际中,有时为了提升响应,会用到异步线程处理,对于异步线程,默认是不会带压测的标识,因而需要在代码中进行处理。同时对于一些关键的埋点日志,也要避免压测数据影响埋点日志,这些数据要么新建日志,要不不但要日志,需要根据不同的业务要求来确定。另外需要考虑的就是缓存,也要考虑压测数据的污染,如果缓存空间够用,那还ok;如果不充足,也需要进行处理。
在压qps时,要考虑请求数据的问题,要不然会形成两个极端:全部走db或者全部不走db。对于全部走db的情况,如果数据样本不够大的情况,很可能会形成单点,造成db过早到顶。对于全部不走db的情况,可以采用下面的方案予以实现:设置一个可以通过jmx动态调整的属性,该属性取值范围为0到100,当压测请求过来后,生成一个100以内的随机数,如果生成的随机数大于该属性值,则强制到db,否则使用缓存,通过这种方法可以大致的控制访问db的数据量。总结起来在进行压测前需要进行如下的准备:
1) 判断请求是压测请求
2) 影子表创建
3) 缓存访问改造
4)异步线程压测改造
5)关键埋点日志区分
在这些压测改造完成后,还需要和压测团队进行下联调,以确保这些改造生效,写请求能够写到影子表中,读请求能够控制到达db的量。
5 压测
在压测准备工作完成后及联调通过后,就可以进行压测了。从压测的目的上可以分为两种:摸高和达标。摸高,顾名思义,就是要找到自己系统的最大服务能力。达标则是看自己的系统能否达到上游系统的期望的tps/qps需求。这两个不同目的的压测进行的操作是相同的,只是对于摸高压测,自己要设定下指标,达到什么条件算是摸高,通用的目标主要包括cpu、load、rt、内存、用户线程占比等。
6 扩容、确定预案配置(降级预案和应急预案)
如果压测时能满足上游系统的要求,则皆大欢喜,可以安心睡觉,静待大促的到来了。但通常这种情况难得发生,如果真是这样,大促制定目标的同学该下下课了,这时就必须考虑下该如何应对了。
常用的方法:扩容、业务降级和限流。扩容比较好理解,应用服务器不够,加应用服务器;db不够,加db;缓存不够,扩缓存空间。扩容对开发人员来讲是比较简单的,但是对老板就不一样了,那是需要白花花银子的。即使预算足够,扩容还受限于机房的限制,不可能没有无穷的扩容下去,如果达到机房的瓶颈后,就需要考虑整体部署架构的调整了。当无法扩容时,就需要考虑业务降级了,把整个链路中一些业务处理逻辑去掉,尽可能的精简,只保留最最关键的业务,丢卒保车。如果这个还不行,就需要考虑限流了,让用户的请求来的不那么猛烈,像以前的小米手机的发售或者火车票的发售那样,在网关就把请求拦截掉,适当的牺牲下用户的体验。根据对用户的影响程度大小及,可以将降级措施分为日常降级、高峰降级和应急降级,将这些降级指定成预案,确定预案的执行时机。
7 限流配置
可能会有同学会问,既然经过了压测,也进行了扩容,也有了各种预案,为啥还需要限流,限流还要消耗服务器的性能?原因在于前面的压测的各项指标,是根据日常情况及以前的历史估算得到的,但是这个毕竟不是真实值,如果用户的真实访问超过了估算值,那应该如何应对,如何不被压垮?这个时候靠的就是限流,毕竟预案的推送生效是需要时间的,为避免系统恶化,限流是一道很有效的防护措施。
8 演练、修正
在经过了系统改造,制定了预案、设置了限流,就需要回过头来再次进行压测,以确定这些预案是否达到了期望的qps/tps。这个过程可能会持续好几轮,直到达到目标。