NingG +

大型网站架构:熔断、降级、限流

0.概要

微服务架构中,服务数量增加,整体系统可用性会存在潜在问题,因此,需要一些额外的措施。

具体几个方面:

  1. 问题:分布式系统架构中,存在的问题
  2. 解决方法:上述问题的解决办法?
  3. 注意事项
  4. HyStrix 框架的原理

特别说明:

Hystrix 已经进入「维护状态」,现在 Netflix 已经启用「resilience4j」框架,作为替代方案。

1.问题

分布式系统,随着业务复杂度提高,系统不断拆分,一个面向 C 端的 API 调用,其内部的 RPC 调用层层嵌套,调用链变长,会造成下述 2 个问题:

  1. API 接口可用性降低
    • 假设一次 api 请求,内部涉及 30 次 rpc 调用
    • 每个微服务可用性 99.99%
    • 则,api 请求的可用性为 99.99% 的 30 次方 = 99.7% ,即,0.3% 的失败率
  2. 系统阻塞,拒绝请求接入
    • 假设一次 api 请求,内部涉及 10 次 rpc 调用
    • 只要 10 次 rpc 中,有一次请求超时,则,整个 api 调用就超时了
    • 如果大量请求突发访问,则,大量的线程都阻塞(block 等待超时)在这一服务上,新的请求无法接入

2.解决方法

为了解决上述「API 接口可用性降低」和「系统阻塞、拒绝请求接入」问题,可以采用下述 4 中方法:

  1. 熔断:服务熔断,一旦触发「异常统计条件」,则,直接熔断服务,在「调用方」直接返回,不再 rpc 调用远端服务;
  2. 降级:降级是配合「熔断」的,熔断后,不再调用远端服务器的 rpc 接口,而采用本地的 fallback 机制,返回一个「备用方案」/「默认取值」;
  3. 限流:限制「速率」,或从业务层限制「总数」,被限流的请求,直接进入「降级」fallback 流程;
  4. 异步 RPC:通过异步访问,提升系统访问性能;

2.1.熔断

为了防止大量请求都被 block 到某个服务上,导致大量线程、端口被占用,无法处理新请求,则,引入「服务熔断」概念。

HyStrix 框架下,实现「服务熔断」的底层原理:

具体 HyStrix 框架的 hello world 逻辑:

// 客户端:封装原生的 rpc 调用逻辑
public class CommandHelloWorld extends HystrixCommand<String> {
​
    private final String name;
​
    public CommandHelloWorld(String name) {
        super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
        this.name = name;
    }
​
    @Override
    protected String run() {
        //关键点:把一个RPC调用,封装在一个HystrixCommand里面
        return "Hello " + name + "!";
    }
}
​
// 客户端调用:以前是直接调用远端RPC接口,现在是把RPC接口封装到HystrixCommand里面,它内部完成熔断逻辑
String s = new CommandHelloWorld("World").execute();

隔离策略线程池 vs. 信号量

上面的代码实例中,默认情况下,HystrixCommand 是「线程隔离策略」,即,直接在线程池中,获取新的线程,来执行 rpc 调用。

另外,还有一种策略是「信号量隔离策略」,直接在「调用线程」中执行,通过「信号量」进行隔离。

Think:

上述隔离策略「线程池」和「信号量」,有什么优劣?适用场景?

上述「线程池」和「信号量」2 种隔离方式,其优缺点:

熔断参数的设置:熔断器的参数

上述 3 个参数,放在一起的物理含义:

每当20个请求中,有50%失败时,熔断器就会断开,此时,再调用此服务,将不再调远程服务,直接返回失败。

5s 后,重新检测该触发条件,判断是否熔断器连接,或者继续保持断开。

2.2.降级

降级,是配合「熔断」存在的。

降级,就是服务熔断之后,不再调用服务器的 rpc 接口,客户端直接准备一个本地的 fallback 回调,返回一个缺省值。

影响

2.3.限流

限流,在现实生活中,也比较常见,比如节假日去旅游景点,管理部门通常会在外面设置拦截,限制景点的进入人数(等有人出来之后,再放新的人进去)。

对应到分布式系统中,比如活动、秒杀,也会限流。

关键点:限流的目标和依据,是什么?

常见的,限流依据下述参数进行:

  1. HyStrix 中:
    1. 线程隔离时,线程数 + 排队队列大小,来限流
    2. 信号量隔离时,设置「最大并发请求数」,来限流
  2. 并发数量:QPS、并发连接数等
  3. 总量:业务层中,限制「库存」总量等

限流技术原理:

TODO:

2.4.异步 RPC

异步 RPC,主要目标:提升系统的接口性能,从而提升并发处理能力。

启用「异步 RPC」,有一个前提,异步 RPC 之间,不存在「相互依赖」。

实例:

  1. 比如你的接口,内部调用了3个服务,时间分别为T1, T2, T3。
  2. 如果是顺序调用,则总时间是T1 + T2 + T3;
  3. 如果并发调用,总时间是Max(T1,T2,T3)。

一般成熟的RPC框架,本身都提高了异步化接口,Future或者Callback形式。

同样,Hystrix 也提高了同步调用、异步调用方式,此处不再详述。

3.总结

熔断、降级、限流、异步 RPC,都是分布式服务框架中,常用的策略,能够提升系统稳定性、容错性。当前大部分服务框架,都对这些策略,有比较好的原生支持。

4.参考资料

同类文章:

微信搜索: 公众号 ningg ,即可联系我

Top