You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

97 lines
11 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 11雪崩降级无奈的丢车保帅之举
你好,我是陈现麟。
通过学习限流的内容,我们掌握了限流机制的应用场景、实现原理和关键问题,这样我们就可以为极客时间后端的分布式系统,在关键路径和核心服务上,去引入限流机制,进一步提高系统的稳定性。
但是,在系统因为过载而出现故障的时候,虽然熔断机制可以确保系统不会雪崩,限流可以确保,被保护的服务不会因为过载而出现故障,可是这时候,系统的可用性或多或少都会受到一定的影响,并且这个影响不会区分核心业务和非核心业务。
那么你的脑海里一定会出现一个想法,是否可以在故障出现的时候,通过减少或停掉非核心业务,来降低系统的负载,让核心业务不会受到,或者少受到影响呢?其实是可以的,这就是一个典型的降级场景问题。
在这节课中,我们将一起讨论保障分布式系统稳定性的第三个方法——降级,分析如何通过降级机制,来保障系统的核心服务稳定运行。这节课我依然会按照需要降级的原因,如何实现降级,以及降级机制应该注意的关键问题这一条思路来为你讲解。
## 为什么需要降级
为什么有了熔断和限流之后,我们依然需要降级机制呢?在分布式系统中,熔断、限流和降级是保障系统稳定性的三板斧,缺一不可,并且在保障系统的稳定性方面,降级有着熔断和限流所没有的优点,因此它们之间相互配合和补充,能够最大限度地保障系统的稳定性水平。
**首先,降级机制能从全局角度对资源进行调配,通过牺牲非核心服务来保障核心服务的稳定性**。比如,在当前极客时间的后端系统出现了过载问题的时候,或者我们预计到由于运营活动会出现突发流量的时候,我们有账号、支付和评论三个服务,停掉任意一个服务都可以让系统正常运行,那么相对于账号和支付这两个非常核心的服务,毫无疑问,我们会选择停掉评论服务来丢车保帅,降低系统故障对外的影响,这其实就是降级的核心思路。
你可能会想到,通过限流机制也可以出现降级的效果,比如,直接将评论服务的请求 QPS 限制为 0但是本质上来说限流和降级机制的思维方式还是不一样的。限流一般是通过对请求流量控制来保证被限流服务的正常运行而降级却恰恰相反它是通过牺牲被降级的接口或者服务来保障其他的接口和服务正常运行的。
**其次,降级可以提高系统的用户体验性和可用性**。在分布式系统中,如果接口的正常调用出现非业务层错误后,在某些情况下,我们可以不用直接返回错误,而是执行这个接口的“ B 计划”进行降级。虽然降级后的执行结果没有正常调用那么完美,但是和直接返回调用错误相比,这对系统的用户体验和可用性来说,却是一个不小的提升。
在这个场景下,降级可以和熔断、限流机制配合使用,在系统触发熔断和限流的时候,我们可以不直接返回错误,而是执行预先准备好的降级结果。降级需要提前设计,并且降级的逻辑也要消耗系统资源,所以一般来说,对于核心的接口或服务,我们可以通过缓存或者其他的方法来提供一些,一致性等方面较差,但是业务可以接受的返回结果;而对于非核心的接口和服务,我们可以考虑通过友好的提示等低成本的方式,来提升用户的体验。
这里一定要注意,降级在和熔断、限流机制配合使用时,一定要评估降级逻辑的性能,千万不能因为降级逻辑,再次导致系统雪崩。
## 如何实现降级
通过上面的讨论,我们了解到在故障出现的时候,降级机制可以从全局角度,提高系统资源使用的效率,进一步提升系统的稳定性和用户体验,而且这一点是熔断和限流机制都无法替代的。那么我们该如何实现降级机制呢?下面我们根据降级操作是否由人工触发,将降级机制分为手动降级和自动降级,来一一介绍。
### 手动降级
手动降级是指在分布式系统中提前设置好降级开关,然后通过类似配置中心的集中式降级平台,来管理降级开关的配置信息,在系统需要降级的时候,通过降级平台手动启动降级开关,对系统进行降级处理。
手动降级由人工操作,有可控性强的优点,但是一般来说,一个分布式系统中,会有成百上千的服务和成千上万的实例,如果在出现故障的时候,一个接口、一个服务地去手动启动降级开关是非常低效的。
对于这个问题,有一个可行的方案是,通过对降级分级,利用服务的等级信息和业务信息进行批量降级,具体的思路如下。
首先,将系统中的所有服务,按照对业务的重要程度进行分级,这里,我分享一个服务定级的标准,具体定义见下表。这个标准从高到低按重要程度分为 P0 ~ P3 这 4 个级别,你可以作为参考,依据自己的业务形态进行调整。
![](https://static001.geekbang.org/resource/image/53/00/53c9e6ac73eaf685954e4130a1333a00.jpg?wh=2284x1221)
然后,根据服务的等级信息、业务信息和调用链路的依赖关系,对非核心服务建立分级降级机制。这里以服务为粒度进行分级,实际工作中,如果有需要也可以以接口为粒度进行分级。假设 P0 为核心业务,其他的为非核心业务,我们可以简单地将降级分为以下 3 个级别。
* **一级降级:会对 P1、P2、P3 的服务同时进行降级**。
* **二级降级:会对 P2、P3 的服务同时进行降级**。
* **三级降级:会对 P3 的服务同时进行降级**。
这样在需要降级的时候,我们就可以根据系统当时的情况,按接口、服务和降级级别进行手动降级。当然在实际操作中,你还可以综合业务场景来设置降级级别,并且根据业务需要来设置更多的降级级别。这里要注意,不论是服务分级还是降级分级,都是需要谨慎对待的一件事情,如果出错将会导致人为的故障发生。
### 自动降级
自动降级是指在分布式系统中,当系统的某些指标或者接口调用出现错误时,直接启动降级逻辑,但是因为自动降级不能通过开关来控制,所以需要认真评估。一般来说,系统关键链路上的“ B 计划”可以进行自动降级,否则业务将无法正常提供服务。
这里我们来看一个鉴权接口自动降级的例子。假设我们在网关中调用鉴权服务进行鉴权,每一个调用鉴权服务的鉴权接口,需要执行如下的两个校验逻辑,不论哪一个失败,都会导致鉴权失败。
**1\. 校验 Token 是否合法**
**2\. 校验 UID 是否被管理员封禁**
在这个情况下,我们可以将 Token 设计为可以自校验的,在鉴权服务出现故障的时候,则启动降级逻辑,直接在网关中校验 Token 是否合法如果合法就返回鉴权成功。因为在大多数业务场景中Token 被管理员封禁是小概率事件,所以相对于所有用户都不能正常鉴权的情况,我们认为个别被管理员封禁的用户也可以鉴权成功,是完全可以接受的。
其实,我们可以将自动降级理解为手动降级的特殊情况,即降级开关为启用的手动降级。所以,还有一个思路就是,不提供自动降级,在需要自动降级的场景下,通过降级开关为启用的手动降级来实现,这样还可以进一步提高降级的灵活性。
## 降级机制的关键问题
学习完降级的实现原理后,我们就知道了如何在自己的系统中引入降级机制了。但是一般来说,我们使用降级都是在系统已经出现过载的场景下,这时我们需要考虑,降级的配置信息是否能正常下发。并且,降级通常会与熔断和限流一起出现,我们应该如何处理它们三者之间的关系。基于这两点,在降级机制实际使用的过程中,我们还需要思考下面两个关键问题。
### 配置信息下发的问题
对于熔断和限流来说,其阈值相关的配置信息在系统正常运行的时候,就已经下发到实例上了,所以在系统出现故障的时候,这些配置信息会直接生效。但是对于降级机制来说,如果采用了手动降级的机制,并且默认设置为关闭,在系统出现故障的时候,我们需要通过降级平台下发配置来启动降级。
但是在系统出现故障的时候,有可能会出现降级配置无法正常下发的情况,这时我们将不能启动降级策略。我们可以考虑,由服务直接暴露出修改降级配置的 HTTP 接口,在必要的时候,可以手动通过 HTTP 接口,来启动服务的降级逻辑。
### 熔断、限流和降级之间的关系
在分布式系统中,熔断、限流和降级是保障系统稳定性的三板斧,经常一起出现,很容易导致混淆,所以,下面我们就对熔断、限流和降级机制之间的关系进行比较和总结:
首先,因为熔断机制是系统稳定性保障的最后一道防线,并且它是自适应的,所以我们应该在系统全局默认启用;其次,限流是用来保障被限流服务稳定性的,所以我们建议,一般在系统的核心链路和核心服务上,默认启用限流机制;最后,降级是通过牺牲被降级的接口或者服务,来保障其他的接口和服务正常运行的,所以我们可以通过降级直接停用非核心服务,然后对于核心接口和服务,在必要的时候,可以提供一个“ B 计划”。
其实,从整个系统的角度来看,不论是熔断还是限流,一旦触发了规则,都是通过抛弃一些请求,来保障系统的稳定性的,所以,如果更广泛地定义降级的话,可以说熔断和限流都是降级的一种特殊情况。
## 总结
我们掌握了需要降级机制的原因,以及实现原理和关键问题,一起来总结一下这节课的主要内容。
通过讨论有了熔断和限流机制之后,依然需要降级机制的原因,我们了解了限流的作用和应用场景,在后续的工作中碰到相关的问题时,可以引入降级机制。
另外,我们一起分析了如何实现降级机制,从操作的角度来讲,降级分为手动降级和自动降级,掌握了这些知识和原理后,你就能为你现在的系统实现一个降级机制了。
我们还一起探讨了限流机制的关键问题:配置信息下发的问题,以及熔断、限流和降级机制之间的关系,这样一来,你不仅能实现一个健壮的降级机制,并且还能更好地理解熔断、限流和降级三者之间的关系。
## 思考题
保障分布式系统稳定性的三板斧,熔断、限流和降级都已经讨论完了,欢迎你来分享一下自己对熔断、限流和降级的理解。
欢迎你在留言区发表你的看法。如果这节课对你有帮助,也推荐你分享给更多的同事、朋友。