服务化架构-服务降级

1. 什么是降级

高可用系统为了保证自身的高可用性,会在异常情况下限制自身的一些能力,来保证核心功能的可用性。这有点类似武侠小说里面的壮士断腕,也有点类似于象棋里面的弃车保帅。

2. 为什么需要降级?

在系统复杂度越来越高的今天,我们可能会经常遇到这样的困扰:一个非核心的功能异常最终导致了整个系统的不可用。比如一个获取非核心数据接口的超时最终导致了整个线程池全部阻塞,影响了核心功能线程的运行;业务链条中某个环节的接口不可用导致整个业务链的失败。这样的例子比比皆是,造成的损失往往也非常大,所以为了避免这种小功能搞垮大系统的情况发生,降级的概念就应运而生了。

3. 降级预案

在要对系统制定降级策略之前,我们先对系统中的功能、服务进行梳理,识别出系统中的核心、非核心功能,这样能够梳理出哪些失败需要阻断主流程,哪些失败可以不阻断主流程。这样我们也就能确定哪些功能和服务必须死保,哪些功能和服务能够降级。
举个栗子:在机票的搜索流程中,报价、航班详情(如起降时间、航站楼)是关键信息,这些信息是无论如何不能缺失的;但餐食信息对于用户来讲就是可有可无的,当系统压力比较大的时候,我们就可以将餐食信息的获取给关掉,来优先保证核心数据的正常获取;
再举个栗子:对于机票的信息中,报价信息是经常变化的,但航班详情信息变化频率就没那么大。那么在系统压力比较大的情况下,可以将获取航班详情的方式由实时获取改为读取缓存,这样既不会导致数据准确性有太大的变化,也保证了系统核心功能的可用。

4. 降级策略

4.1 按功能降级

按功能降级是指在不影响核心功能的情况下,减少对非核心功能的使用,来保护系统的基本使用。
比如前面提到的例子,在机票搜索过程中,如果系统负载比较大出现超时,可以先将中转拼接报价计算功能(非核心功能)关闭,减少计算量,来降低系统负载保证用户搜索不至于失败;
再比如,在双11或者618的时候,系统的负载往往都比较大,这时候为了降低系统的负载,系统往往会把诸如支付后推荐、买了又买之类的非核心功能关闭。这些case我们可以参考淘宝、京东同学写的技术文章,例子不胜枚举。

4.2 按来源降级

在某些时候,系统的QPS比较高,服务器扛不住压力的时候,可以针对请求进行限流。当然对于限流我们不能一刀切,如果能先限制某些不重要业务的访问,那是最好的。如果所有请求的重要程度是一样的,那么只能按照统一的策略进行限流了,毕竟牺牲掉部分用户请求来保证服务的可用性是第一位的。

4.3 按质量降级

比如利用缓存。在机票行业,飞机上的舱位就相当于电商行业的库存,不同的是,电商的库存基本是自己管理,但机票的库存(舱位)是航司管理的,查询可用舱位花费的成本又很高。为了解决成本,我们可以针对某些冷门航线的舱位使用缓存,而且缓存时间设置得比较久,毕竟这些航线出票量比较少,没必要去占用过多的查询指令。

5. 降级介入方式

在系统遇到异常情况时,我们需要执行事先准备的降级预案,这时候就需要额外的分支介入系统逻辑,来执行系统降级策略。降级的介入方式分为两种:人工介入和自动介入。当然有的时候在系统所处的局面比较复杂的时候,往往需要两者方式都需要使用,比如自动降级失效的情况下,那么必须进行人工介入了。

5.1 人工介入

人工介入的方式是指当系统维护人员在发现系统异常之后,通过人工修改参数、关闭服务等方式进行降级的方法。这种方式的好处是比较灵活,能够根据异常情况灵活应对;但弊端是对人的要求比较高,一来需要维护人员对系统有足够的了解,另外要求维护人员在系统异常时能够在第一时间进行处置。

5.2 自动介入

自动介入的方式一般是当系统达到某些设定的条件之后,自动执行一些策略。比如当系统以来的某个第三方数据接口的失败率达到设定的阈值,那么就使用缓存数据;再比如购买机票的时候,如果遇到航司接口维护,那么我们可以先收单,保证主流程不阻断,等航司接口恢复之后再执行出票处理。