1.3、分布式之弹性:服务降级

一、简介

​ 服务不论如何优化,总会有达到瓶颈的时候,在资源不足,请求量过大的情况下,服务本省可以使用一些策略,提升服务的吞吐量触,发降级处理就是策略之一。

​ 所谓的降级服务其实就是牺牲掉一些逻辑处理,或者停止部分依赖服务的请求。以保障服务可以提供关键能力。这么来看,服务降级很难做到不侵入业务,这种降级逻辑都是预埋在服务内的。

二、降级处理

2.1、一致性降级

​ 一致性降级处理一般分为两种,一种是写流程上采用异步处理,一种读流程上采用缓存的形式。这些做法都是将强一致性转化为最终一致性。

2.1.1、异步化处理

在CMS上对于用户上传的数据源一般会有必须要进行的几步处理,

  • 机器审核->人工审核->运营标准化处理->上线处理

这种流程就是典型的先审核,后发布。没有经过机器审核,以及人工审核就不让发布。这种流程可以保证数据的安全性,但是这种强一致性的处理很大程度上依赖我们的运营资源,资源不足的情况下,会有大量的数据积压。

降低一致性的处理上,我们可以把流程修改为先发后审,通过了机器审核后,就可以发布。为了安全性,我们可以先保证该数据不被推荐,或者搜索出来。只可以在个人中心页中看到。后面人工审核到的时候如果该内容不符合要求则下线,如果通过,在通过标准化运营,让该内容在首页曝光。也就是从强一致性,转变为最终一致性,视频的发布不再依赖运营资源。

2.1.2、缓存处理

使用缓存就是降低数据的一致性。缓存也可以有效降低数据库的压力。

  • 命中,直接返回数据
  • 失效,因为LRU或者是其他缓存策略,导致缓存失效。那么从数据库中读取数据,读取成功后,把数据放入缓存。
  • 更新,写入数据库成功后,让缓存失效。

缓存更新一般有两种模式:

  • Read Through:查询的时候更新,服务自己加载缓存。
  • Cache Aside:调用方去主动加载缓存。

综合来看,缓存也可以在服务降级中产生很大的作用。但是该缓存哪些数据,缓存策略是什么,缓存的有效期是多少?这些都需要业务方主动来设计。从这点可以看出,服务降级本身和业务是很相关的。

2.2、依赖降级

​ 停止一些依赖服务的请求,是服务降级处理中很有效的一种办法。让系统释放出更多资源,可以有效处理更多请求。举一个例子,我们在服务中会做很多数据上报,例如在个人中心页,有很多视频列表,要曝光视频的信息。有时候需要上报的信息需要请求其他服务获取。在降级处理中,这种服务依赖就可以停止掉。

​ 如果没有这种以来服务可以降级,其次优先选择非关键信息。例如头像信息,甚至是一些评论,点赞功能,等等。非关键功能的降级最好不要发生,因为这种降级毕竟是有损用户体验的。

2.3、功能分级

​ 其实可以给接口做分级,像是一个获取视频信息的接口,这个信息可能会很多,视频id,是否审核通过,播放地址,上传时间,上传用户,是否标准化等等。

​ 很多时候对于一些服务来说,本身就是要部分信息,比如播放地址,视频名就可以了。但是因为是基础服务,越来越多的人服务依赖,返回的信息页越来越全,越来越重。这种发生降级处理的时候,可以直接返回一些重要的基础信息。

​ 基础服务可以针对自己不同的业务场景,去对接口进行分级,针对不同的级别,决定返回数据的粒度。

三、降级处理的关键

3.1、服务设计

​ 降级处理是很侵入服务的,所以最好在服务设计的时候就去考虑,哪怕是不实现,可以先把方案准备好。到了一定量级根据之前设计的方案去实现。

​ 降级方案的选择,需要梳理清业务,选择好对流程降级,还是对数据量级?做好日志,方便我们查询问题。

总结:写处理降级使用异步化处理,读处理降级使用缓存。

3.2、开关配置

​ 降级要能通过开关动态开启或关闭,可配置化,或者在接口设计中有固定的开关参数,可以让调用方决定是否采用降级请求。例如,服务发生限流,在协议头中标记为限流处理,调用方拿到回包发现目标服务正在执行限流,重试的时候就可以决定是否采用降级请求。

3.3、上线前验证

​ 降级设计需要在上线前进行演练验证,防止上线后真的发生降级处理,而出现意外问题。

四、总结

服务降级本质为了解决在有限资源条件下,为了更大程度处理请求。将强一致性改为最终一致性是很有效的方案,写可以使用异步化处理,读可以使用缓存。