笔者在工作中,主要维护所在bg的营销活动的列表,活动的列表像商详页或团详页一样需要聚合大量服务提供的数据,而且作为后两者的入口,活动列表出不得任何闪失,否则结局必是灾难性的。每一次的大促活动能否平安度过,取决于平日准备时对这些下游服务更好地把控。熔断降级作为最基本和有效的手段,保证了服务的柔性可用,提高系统整体的可用性与稳定性。接下来就谈谈熔断和降级。
先简单一句话概括,降级就是在调用的下游服务A出现问题(常见超时),提供PLAN-B,返回的效果可能没有服务A好,但是聊胜于无。而熔断器的存在就是要保障何时走到降级方法,何时恢复,以什么样的策略恢复。
接下来,我想举个例子,详细说明熔断降级的作用和必要性。
就用我们公司最有意思的神秘民间组织,美团外卖举例。
如上图,我们公司在该地区一共有4个外面小哥,编号0-3;该地有6家流行餐厅,几乎是用户必点。编号从A-F。故事开始前,我们做如下假定:
(1)外卖火爆,几乎外卖小哥每次在外都能接到不止一单,且是不同的餐厅;
(2)外卖小哥都是耿直的人,不取完本次接单的几家餐厅,不轻易送餐。
一切看起来很和谐,直到有一天,餐厅A出事了,主厨的大叔失恋了,出餐的速度大降。每个要去餐厅A取餐的小哥都要花费更长的时间在A等餐。而且餐厅A越流行,出餐速度越慢,排队等待的小哥就会越多。在上图中,最后4个外卖小哥,有3个都排队在等A餐厅的饭食。这有两点直接影响:
(1)不光是A,其他餐厅单子也还没有配送,用户吃不到A的饭,就连其他用户点的B、C、D的饭也不能配送,差评,卸载,美团一生黑;
(2)3/4的外卖小哥处于低效率地排队等待,而不是送餐,降低了整个公司在该地区的配送效率,老王坐不住了。
然而,正如江湖传言,美团外卖是个神秘的组织,有一天,一个机智的小哥,横空出世,改变了整个行业的布局。
小哥在餐厅A亲自操刀,很快就做完后,送餐了。用户收到热乎乎的饭菜,吃起来没有以前的好吃,但也觉察不出任何异样,不会投诉;整个地区的小哥又重新流通起来,恢复到大叔失恋前的配送效率。
后来,在公司的内部总结中。发现不光是A餐厅的大叔会失恋,C餐厅D餐厅的大叔们也偶尔失恋,影响出餐速度。后来公司和这些餐厅们商量,为更好的规范化出餐流程,各餐厅新添加二叔,二叔厨艺一般,请二叔各餐厅花费成本不高,所以纷纷表示赞同。
在实践的过程中,小哥和大叔二叔们约定,如果在规定时间和次数,大叔不能按时出参,那么二叔替代大叔,接相同的单,用同样的锅;大叔的出餐速度会被定期检查,是否恢复了正常水平,恢复了之后,单子慢慢还由大叔下厨。
现在,我们来对应下关系。
美团外卖大本营——容器,常见的如tomcat,jetty的线程池
外卖小哥——线程
餐厅——服务接口
二叔——降级方法
大叔到二叔的切换——熔断
恢复大叔下厨——熔断降级的恢复策略。
熔断保证了下游服务在出错率达到阈值时,上游调用切换到降级方法,提供有损服务,避免服务的级联失败,影响整个系统的稳定性。熔断的时机,取决于业务的实际场景和流量大小,不要过高,也不要过低;恢复的策略,其核心是恢复的速率,不要过快也不要过慢。一句废话,看需求。
在公司,我们有自己的故障演练分析防护的平台,由于没开源,不便过多闲话。在开源社区,也有很多相应的产品,比较推荐的,也是目前使用较为广泛的是NetFlix的Hystrix,Hystrix是个完善的容错库,实现了熔断降级、线程隔离、限流等多种功能,开箱即用,有需要的朋友速速入手吧。