在高可用架构的讨论中,我们已涉及了相关概念。这次我们聊的就是「高可用三剑客」中剩下的「降级」。
在每次大促的时候,平台都会发布相关的公告调整。这些调整就是「降级」工作,目的是为了腾出更多资源给核心程序使用,以最大化保证核心业务的可用性,因此就必然需要对非核心业务执行一些降级处理。
什么是「降级」
降级的目的用一句话概括就是:将有限的资源效益最大化。
什么样才是效益最大化呢?就像下面这个例子:
用户有 3 个东西要买,一个 3000 的 A、一个 700 的 B、一个 1200 的 C,对用户的重要程度 A>B>C。但此时,用户手里只有 3000 块钱,你说用户该怎么选才能把钱花的最多?必然是选 A 咯。
根据二八原则,我们知道一个系统 80% 的效益是由最核心的 20% 的功能产出的。剩下的 20% 效益需要投入 80% 的资源才能达到。
这就意味着,假如系统平时需要花费 100% 资源做 100% 的事情,如果现在访问量增多 3 倍的话必定扛不住(需要 300% 的资源)。那么,在不增加资源的情况下,我希望系统不能宕机,依旧能正常工作,必然需要让出那解决剩下 20% 问题的 80% 资源。如此一来,理论上这 100% 的资源就可以支撑原先 5 倍的访问量。副作用是功能的完整性上受损 80%。
当然,在实际的场景中不会降级掉 80% 的功能这么夸张,毕竟还得为用户的体验考虑。
举个电商场景典型的例子,在大促的时候,最重要的是什么?转化咯~赚钱咯~ 那么这个时候如果说「评论」功能占用了很多资源,你会怎么处理?其实我们可以选择临时关闭提交评论入口、关闭翻页功能等等,让下单的过程有更多的资源来处理。
常见的降级方案表现形式无非以下三种类型。
-
牺牲用户体验
为了减少对「冷数据」的获取,禁用列表的翻页功能。
为了放缓流量进入的速率,增加验证码机制。
为了减少'大查询'浪费过多的资源,提高筛选条件要求(禁用模糊查询、部分条件必选等)。
用通用的静态化数据代替「千人千面」的动态数据。
甚至更简单粗暴的,直接挂一个页面显示「XX 功能在 XX 时间内暂时关闭」。
此类方案虽然或多或少降低了用户的体验,但是在某些时期,有些功能并不是「刚需」。以此换取对系统的保护是笔划算的买卖。
-
牺牲功能完整性
还有一些功能是**「防御性」**的,如果愿意冒险'裸奔'一段时间也会带来可观的资源节约。
比如通过临时关闭「风控」、取消部分「条件是否满足」的判断(如,将积分商品添加到购物车时判断积分够不够)等操作,减少这类「验证」动作以释放更多的资源。
又或者将原本 info、warning 级别的日志采集关闭或者直接不采集,仅采集 error 以及 fault 级别的日志。
-
牺牲时效性
一个事件发生后立马看到效果是一个很符合「思维惯性」的东西。但是根据之前的一篇文章我们知道,时效性这个东西一旦涉及到网络传输是不存在真正的'实时'的。但是为了尽可能快的将处理后的结果反映到相关的地方,你会做很多努力。比如库存的及时同步。
如果在特殊时期,能够临时降低对时效性的要求(3 秒内生效变成 30 秒生效),也是一个有不错收益的方案。
比如原先在商品页会显示当前还剩多少个库存,现在可以调整成固定显示**「有货」。**
以及将一些原本就是异步进行的操作,处理效率放缓,甚至暂缓一段时间。如,送积分、送券等等。
讲了这么多,降级具体实施起来要怎么做呢?
「降级」怎么做
主要分为两个环节:定级定序和降级实现。
-
定级定序
就像前面的例子中提到的一样,首先我们得先确定每个功能的「重要程度」,它决定了在什么情况下可以抛弃它以保证剩下的功能可用。
类似于给日志定义级别一样,比如我们可以定义 1~5 五个级别,1 的级别最高,要拼死保护。5 的级别最低最先可以被降级掉。
一旦当系统压力过大的时候,先把级别 5 的功能降级掉。如果还不够再降级别 4、级别 3,以此类推。
但实际上光这样定级还不够,比如被定义为 4 级的有 100 个功能,需要降级的时候是一起降级吗?很明显粒度太粗了。
如果**「定级」**好比是横着切蛋糕的话,「定序」就是再来竖着切。
我们也可以来定义一些数字,比如序号 1~9,序号 9 最先被降级。
然后,你可以以每个程序所支撑的上游程序/功能数量作为一个参考标准。比如,同样是级别 5 的程序,一个支撑了上游 5 个功能,一个支撑了 10 个功能,很显然前者的序号应该更大,更先被降级。
当然,根据所支撑的功能数量只是一个「业务无关性」的通用办法。如果想精益求精,还需要对每个功能做「作用」上的分析,毕竟不同功能之间的相对重要性还是有所差异的。(这里可以扩展了解一下 Analytic Hierarchy Process,层次分析法,简称 AHP)


