- 接口级故障的典型表现就是系统并没有宕机,网络也没有中断,但业务却出现了问题。例
如,业务响应缓慢、大量访问超时、大量访问出现异常(给用户弹出提示“无法连接数据
库”),这类问题的主要原因在于系统压力过大、负载太高,导致无法快速处理业务请求,
由此引发更多的后续问题。例如,最常见的数据库慢查询将数据库的服务器资源耗尽,导致
读写超时,业务读写数据库时要么无法连接数据库、要么超时,最终用户看到的现象就是访
问很慢,一会访问抛出异常,一会访问又是正常结果。
导致接口级故障的原因一般有下面几种:
内部原因
- 程序 bug 导致死循环,某个接口导致数据库慢查询,程序逻辑不完善导致耗尽内存等。
外部原因
- 黑客攻击、促销或者抢购引入了超出平时几倍甚至几十倍的用户,第三方系统大量请求,第
三方系统响应缓慢等。
解决接口级故障的核心思想
- 优先保证核心业务和优先保证绝大部分用户
降级
降级指系统将某些业务或者接口的功能降低,可以是只提供部分功能,也可以是完全停掉所
有功能。例如,论坛可以降级为只能看帖子,不能发帖子;也可以降级为只能看帖子和评
论,不能发评论;而 App 的日志上传接口,可以完全停掉一段时间,这段时间内 App 都
不能上传日志。降级的核心思想就是丢车保帅,优先保证核心业务。例如,对于论坛来说,90% 的流量是
看帖子,那我们就优先保证看帖的功能;对于一个 App 来说,日志上传接口只是一个辅助
的功能,故障时完全可以停掉。常见的实现降级的方式有:
简单来说,就是系统预留了后门用于降级操作。例如,系统提供一个降级 URL,当访问这
个 URL 时,就相当于执行降级指令,具体的降级指令通过 URL 的参数传入即可。这种方
案有一定的安全隐患,所以也会在 URL 中加入密码这类安全措施。
系统后门降级的方式实现成本低,但主要缺点是如果服务器数量多,需要一台一台去操作,
效率比较低,这在故障处理争分夺秒的场景下是比较浪费时间的。
熔断
熔断和降级是两个比较容易混淆的概念,因为单纯从名字上看好像都有禁止某个功能的意
思,但其实内在含义是不同的,原因在于降级的目的是应对系统自身的故障,而熔断的目的
是应对依赖的外部系统故障的情况。假设一个这样的场景:A 服务的 X 功能依赖 B 服务的某个接口,当 B 服务的接口响应很慢
的时候,A 服务的 X 功能响应肯定也会被拖慢,进一步导致 A 服务的线程都被卡在 X 功能
处理上,此时 A 服务的其他功能都会被卡住或者响应非常慢。这时就需要熔断机制了,
即:A 服务不再请求 B 服务的这个接口,A 服务内部只要发现是请求 B 服务的这个接口就
立即返回错误,从而避免 A 服务整个被拖慢甚至拖死。熔断机制实现的关键是需要有一个统一的 API 调用层,由 API 调用层来进行采样或者统
计,如果接口调用散落在代码各处就没法进行统一处理了。熔断机制实现的另外一个关键是阈值的设计,例如 1 分钟内 30% 的请求响应时间超过 1
秒就熔断,这个策略中的“1 分钟”“30%”“1 秒”都对最终的熔断效果有影响。
限流
降级是从系统功能优先级的角度考虑如何应对故障,而限流则是从用户访问压力的角度来考
虑如何应对故障。限流指只允许系统能够承受的访问量进来,超出系统访问能力的请求将被
丢弃。虽然“丢弃”这个词听起来让人不太舒服,但保证一部分请求能够正常响应,总比全部请求
都不能响应要好得多。限流一般都是系统内实现的,常见的限流方式可以分为两类:基于请求限流和基于资源限
流。基于请求限流指从外部访问的请求角度考虑限流,常见的方式有:限制总量、限制时间量。
限制总量的方式是限制某个指标的累积上限,常见的是限制当前系统服务的用户总量,例如
某个直播间限制总用户数上限为 100 万,超过 100 万后新的用户无法进入;某个抢购活动
商品数量只有 100 个,限制参与抢购的用户上限为 1 万个,1 万以后的用户直接拒绝。限
制时间量指限制一段时间内某个指标的上限,例如,1 分钟内只允许 10000 个用户访问,
每秒请求峰值最高为 10 万。无论是限制总量还是限制时间量,共同的特点都是实现简单,但在实践中面临的主要问题是
比较难以找到合适的阈值,例如系统设定了 1 分钟 10000 个用户,但实际上 6000 个用户
的时候系统就扛不住了;也可能达到 1 分钟 10000 用户后,其实系统压力还不大,但此时
已经开始丢弃用户访问了。即使找到了合适的阈值,基于请求限流还面临硬件相关的问题。例如一台 32 核的机器和
64 核的机器处理能力差别很大,阈值是不同的,可能有的技术人员以为简单根据硬件指标
进行数学运算就可以得出来,实际上这样是不可行的,64 核的机器比 32 核的机器,业务
处理性能并不是 2 倍的关系,可能是 1.5 倍,甚至可能是 1.1 倍。为了找到合理的阈值,通常情况下可以采用性能压测来确定阈值,但性能压测也存在覆盖场
景有限的问题,可能出现某个性能压测没有覆盖的功能导致系统压力很大;另外一种方式是
基于请求限流
限制总量的方式是限制某个指标的累积上限,常见的是限制当前系统服务的用户总量,例如
某个直播间限制总用户数上限为 100 万,超过 100 万后新的用户无法进入;某个抢购活动
商品数量只有 100 个,限制参与抢购的用户上限为 1 万个,1 万以后的用户直接拒绝。限
制时间量指限制一段时间内某个指标的上限,例如,1 分钟内只允许 10000 个用户访问,
每秒请求峰值最高为 10 万。
排队
- 排队实际上是限流的一个变种,限流是直接拒绝用户,排队是让用户等待一段时间,全世界
最有名的排队当属 12306 网站排队了。排队虽然没有直接拒绝用户,但用户等了很长时间
后进入系统,体验并不一定比限流好。 - 由于排队需要临时缓存大量的业务请求,单个系统内部无法缓存这么多数据,一般情况下,
排队需要用独立的系统去实现。