接口级故障是指系统没宕机、网络也没有中断,但处理业务出现了问题。例如业务响应缓慢、大量访问超时、大量访问出现异常。
这类问题主要是由系统压力太大、负载太高导致的,例如慢查询将数据库服务器资源耗尽,导致连接、读写超时。
原因主要有:
- 内部原因
例如程序死循环、某个接口导致数据库慢查询、程序问题导致耗尽内存 ……
- 外部原因
例如黑客攻击、促销抢购导致访问量暴增、第三方接口响应缓慢 ……
解决接口级故障的核心思想:优先保证核心业务、优先保证绝大部分用户。
策略
1. 降级
将某些业务或者接口的功能降低,停到部分或者全部功能。
核心思想就是丢车保帅,优先保证核心业务。
例如,论坛可以降级为只看帖子,不能发帖;APP 的日志上传接口,可以完全停掉一段时间。
常用的降级方式:
- 系统后门降级
例如提供降级接口,具体指令听过参数传入,访问这个接口就执行了降级操作。
适用于规模不太大的系统,如果服务器非常多,一台台的操作就比较麻烦了,耗时较长,因为故障处理是争分夺秒的。
- 独立降级系统
可以使用一个独立的系统操作降级,例如在分布式配置中心里面操作,使各个系统同时得到降级指令。
2. 熔断
降级是对自身故障的处理,熔断是对外部系统故障的处理,例如:
这时就需要熔断机制,B有问题时,A就不请求了,对B接口的调用直接返回错误,避免被拖死。
熔断的实现需要有一个统一的API调用层,进行采样统计,如果接口调用散落在代码各处就没法统一处理了。
另一个关键是阈值的设计,例如1分钟内30%的请求响应超过1秒就熔断,这几个数字都是不断分析观察优化得来的。
3. 限流
降级是从系统功能优先的角度考虑如何应对故障,限流是从用户访问压力的角度考虑如何应对。
限流只允许系统能够承受的访问量进来,超出能力的将被丢弃。
方式:
- 基于请求限流
是从外部访问的角度来思考,常见的有:
- 限制总量
限制某个指标的累积上限,例如:直播间限制总用户数上限为100万,超出的无法进入;抢购活动限制参与者上限1万个,超出的直接拒绝。
- 限制时间量
限制一段时间内某个指标的上限,例如:1分钟内只允许1万用户访问;每秒请求最多10万。
- 基于资源限流
是从内部考虑的,找到系统内部影响性能的关键资源(连接数、文件句柄、线程数、请求队列等),对其上限进行限制。
例如,采用 netty 实现服务器,每个进来的请求都先放入一个队列,业务线程从队列读取然后处理,队列长度最多1万,满了以后就拒绝请求;根据CPU占用率进行限流,超过80%时拒绝请求。
4. 排队
排队是限流的变种,限流是直接拒绝,排队是让用户等一会儿,例如 12306。
示例一号店的双11秒杀排队系统:
- 排队模块
接收用户的抢购请求,为每个秒杀商品保存一个队列。
- 调度模块
负责动态调度,不断检查服务模块,一但处理能力有空闲,就从队头把访问请求调入服务模块。
调度模块担负着系统调节系统处理能力的重任。根据服务模块的实际处理能力,动态调节从队列拉去请求的速度。
- 服务模块
负责调用业务来处理服务,并返回处理结果。
小结
常用的4种接口级故障处理策略:降级、熔断、限流、排队。
- 降级,对自身故障的处理。
- 熔断,对外部系统故障的处理。
- 限流,从用户访问压力的角度处理。
- 排队,限流的一种变形,把直接拒绝改为等待。
内容整理自《从0开始学架构》