一.问题
接流量告警出现获取 xx 信息接口调用次数同比往年大促活动猛涨.扩大至 10 倍之多.心里顿时咯噔一下.最近各种严打,顶风作案.某不是摸到电门了.一下子要把自己带走.从此走向求职之路.一时间脑子哇哇的思绪万千.
202x.5.20 大促开门红的调用.这个是往年活动的时候的调用量.不到 3k.
202x.5.20 大促开门红的调用.这个是出问题的时间的调用.可以看到每秒 近 2w.qps. 可以看到整体涨的还是比较厉害,要是我的工资也是这样突然就涨的我都不知道就好了.可惜并不是.好了,还是要回来看问题.
二.排查过程
2.1 查看总体流量入口
首先第一反应是不是整体的入口流量导致的就上涨的比较厉害.第一时间去看了入口的流量情况.
今年总量
看看去年的吧.
不看不知道,一看今年更拉.经济不行,买东西的也少了.实锤了.好了,回来从流量入口那基本是排除了因为入口流量上浮原因.
2.2 梳理业务核心链路
这一步就是回来看一下代码本身的现有逻辑,看看在代码链路上有哪些可能的场景会导致调用商家的服务流量上升.本身这个服务是用以渲染整车维度的店铺名称.做了两层的缓存处理用以保证整体的性能以及对于下游的冲击.链路还是比较长.具体看下调用图.
从整体的调用步骤
- 第一步:从整车维度获取所有的店铺 Id.allIds
- 第二步:过滤某些不需要调用的 店铺 Ids
- 第三步:从本地缓存(缓存时间 60s)中获取存在缓存的店铺 Id
- 第四步:从redis 中获取存在缓存(缓存时间 5 分钟)的店铺 Id
- 第五步:将以上两个步骤中已经在缓存中存在的店铺 Id ,从 allIds 中剔除.得到剩余的 restIds
- 第六步:通过服务调用获取剩余 restIds
- 第七步:将获取的服务的 data 设置到 localCache 和 redis 中.
分析以上步骤.大概出问题的点可能是哪些.
第一步:单纯就是因为业务量增加了,店铺的业务数据也多了导致了 allIds 也多了.存在这种可能,可能性不大,因为从前面的流量的入口来看整体的流量已经出现萎缩.
第二步:有些店铺名称是固定的不需要进行调用.这一步需要进行过滤.这一步是在配置文件中配置的.极有可能.最终通过增加了打印日志那些不是去调用的店铺而没有在配置中间中的.找到了这个 id .通过配置加上后.马上流量整体就下降了.我草,这个点确实比较骚.
第三步:缓存集体失效,导致本地缓存为空.存在这种可能.但是有 redis 托底.不至于
第四步:redis 缓存失效.或者读取缓存超时加上本地缓存失效.两者叠加导致增加远程调用量激增.也有这种可能.巧合性高的话
回想最近的大促活动扩容操作,确实有一部分机器出现了很多 redis 读取超时告警.仔细排查了属于跨机房调用.这是属于这一部分原因.
第五步:不可能.逻辑运算
第六步:有可能.服务调用超时.导致无法获取数据.因为咱们的超时的时长都是定长设置.好在是有超时日志告警.但进一步看,没有发现.
排除了这个可能.
第七步:有可能.本地缓存设置失败的和 redis 操作失败都有日志告警.目前没有发现.也排除了这一项.
最近为了迎接大促活动了.做了一些扩容的事情.其中扩容了一部分机器.不看不知道,一看吓一跳.扩容的机器是 lf 机房的机器.调用还是 bj 的缓存集群.
三.改进&扩展
上面的整体流程属于一个比较后置的处理方式.那其实在实际的生产过程中面对这种流量突增的场景到底有哪些措施呢?
- 日常还是活动(大促,整点抢购等)
为什么要有这个区分?在日常的流量过程中应对的策略基本是以保护系统为唯一需要的考量.当然活动的时候这个也是首先要考虑的点.但是还是需要去考虑另外一个点.尽可能去挽留一些正常流量.对于电商场景的话有更多的用户流量肯定是来者不拒的.在日常期间,一般通过限流的来保证日常系统的稳定.
- 服务调用方还是服务提供方
如果是服务方的流量发起方.在确认流量入口无误的场景下.可以提前报备流量预期.保证正常流量可以进来.如果流量比较大且处于一些非核心链路,可以通过主动降级的形式来减少对于服务提供方的调用.具体降级也是可以通过分批的降级的思路,提供一些漏桶的比例.可以在 0-1 的区间做到控制.还有通过增加缓存(本地,分布式)的形式来减少服务提供方的调用.
对于服务调用方,基本是两个方向.
降级
缓存
如果是服务提供方.面对突增的流量.首先保证系统稳定的角度.通过限流(单机,集群)的措施来保证系统平稳运行.如果流量确认正常.并且系统一直有一些 standby 的资源,也可以通过支援的方式来进行线上扩容.支持线上流量.
对于服务提供方
standby 资源支援
限流
内部优化(缓存,内部非核心链路降级,数据库优化)