# 《RPC手撸专栏》第116章:服务熔断基础模型设计

作者:冰河
星球:http://m6z.cn/6aeFbs (opens new window)
博客1:https://binghe001.github.io (opens new window)
博客2:https://binghe.gitcode.host (opens new window)
文章汇总:https://binghe.gitcode.host/md/all/all.html (opens new window)

沉淀,成长,突破,帮助他人,成就自我。

大家好,我是冰河~~

目前,我们自己手写的RPC框架已经完成了整体设计、服务提供者的实现、服务消费者的实现、注册中心的实现、负载均衡的实现、SPI扩展序列化机制、SPI扩展动态代理机制、SPI扩展反射机制、SPI扩展负载均衡策略、SPI扩展增强型负载均衡策略、SPI扩展实现注册中心、心跳机制、增强型心跳机制、重试机制、整合Spring、整合SpringBoot、整合Docker、整合SpringCloud Alibaba、结果缓存、路由控制、延迟连接、并发控制、流控分析、连接控制、SPI扩展连接淘汰策略、数据缓冲、服务容错、服务限流、基于SPI扩展服务限流和超出限流规则等篇章。

# 一、前言

RPC框架已经支持了限流和降级,那能支持服务熔断吗?

服务限流、熔断和降级是保护系统高可用的有力措施,同时,也是系统具备高度容错性的有力保障,在前面的文章中,我们已经实现了服务的限流与降级,那又怎么能落下服务熔断呢?

# 二、目标

目标很明确:服务熔断基础模型设计!

服务熔断一般是指调用方访问服务时通过断路器做代理进行访问,断路器在一段时间内会持续观察服务返回的成功、失败的状态,当失败的次数或者百分比超过设置的阈值时断路器打开,请求就不能真正地访问到服务了,而是通过降级的方式直接返回本地方法或者缓存中的数据。

在逻辑上,是否会触发熔断操作,可以按照规则进行实现:

1.断路器默认处于“关闭”状态,当错误个数或错误率到达阈值,就会触发断路器“开启”。

2.断路器开启后进入熔断时间,到达熔断时间终点后重置熔断时间,进入“半开启”状态。

3.在半开启状态下,如果服务能力恢复,则断路器关闭熔断状态。进而进入正常的服务状态。

4.在半开启状态下,如果服务能力未能恢复,则断路器再次触发服务熔断,进入熔断时间。

本章,我们就实现服务熔断的基础模型设计。

# 三、设计

如果让你设计服务熔断基础模型的流程,你会怎么设计呢?

服务熔断基础模型的流程如图116-1所示。

图116-1

由图116-1可以看出如下信息:

(1)服务提供者会通过自定义类扫描器整合注册中心,将服务注册到注册中心。

(2)服务注册到注册中心的元数据,例如服务的名称、服务的版本号、服务地址、服务端口和服务分组等信息,元数据会贯穿整个服务的注册与发现流程。

(3)服务注册与发现SPI接口对外提供服务注册与发现的方法,服务提供者通过自定义扫描器会调用服务注册与发现SPI接口的方法实现服务注册功能。

(4)基于服务注册与发现的SPI接口,服务提供者会基于SPI接口实现多个服务注册与发现的实现类,每个实现类对应着一种注册中心服务。

(5)服务消费者会通过服务注册与发现的SPI接口订阅注册中心的服务,会从注册中心获取到服务提供者发布的服务信息,实现服务发现的功能。

(6)服务消费者从注册中心获取到服务提供者发布的服务信息后,会基于SPI机制动态加载普通算法(我们将第42章~第50章实现的负载均衡算法统称为普通算法)、基于增强型加权随机算法、基于增强型加权轮询算法、基于增强型加权Hash算法、基于增强型加权源IP地址Hash算法、基于增强型Zookeeper一致性Hash算法和最少连接数算法的负载均衡策略,从多个服务中选择一个进行远程网络连接。

(7)服务消费者会直接与根据基于SPI机制动态加载的负载均衡策略选择出的服务提供者建立连接,实现数据交互。也就是说,后续服务消费者会与服务提供者直接实现数据交互。

(8)服务消费者向服务提供者发送心跳ping消息,服务提供者响应服务消费者pong消息。服务提供者向服务消费者发送心跳ping消息,服务消费者向服务提供者响应pong消息。

(9)服务消费者发送心跳和服务提供者发送心跳,定时任务的时间间隔都是配置化的。

(10)服务提供者与服务消费者除了手动实现定时任务来实现心跳检测外,还基于Netty的IdleStateHandler实现了心跳检测机制。

(11)服务消费者支持服务订阅的重试机制、服务消费者连接服务提供者支持重试机制。

(12)服务提供者支持以Java原生程序方式和整合Spring的方式提供服务,并且实现了基于Spring XML和Spring注解的方式接入RPC框架的服务提供者。

(13)服务消费者支持以Java原生程序方式和整合Spring的方式提供服务。并且实现了基于Spring XML和Spring注解的方式接入RPC框架的服务消费者。

(14)服务提供者支持整合SpringBoot的功能,并支持基于SpringBoot接入服务提供者。服务消费者支持整合SpringBoot的功能,并支持基于SpringBoot接入服务消费者。

(15)RPC框架支持基于Docker接入服务提供者和服务消费者。

(16)结果缓存通用模型中包含:结果缓存的Key和结果缓存管理器。

(17)服务提供者和服务消费者支持结果缓存。

(18)服务消费者支持基于负载均衡延迟/非延迟连接多个服务提供者(这里的多个服务提供者包括从注册中心获取到的服务提供者列表,也包括配置的服务消费者直连的多个服务提供者),或直接延迟/非延迟连接某个服务提供者,调用服务方法(重试机制)

(19)在并发控制基础模型中,会对外暴露核心线程数和最大线程数,对这两个参数进行配置优化,达到并发控制的目的。并且服务提供者和服务消费者支持并发控制。

(20)服务消费者与服务提供者之间的数据交互会异步通过流控分析后置处理器接口的处理。

(21)连接控制基础模型包含两部分:连接管理和淘汰策略,并且连接管理内部会对淘汰策略进行进一步的封装,对外统一提供连接管理的方法。并且,服务提供者整合了连接控制。

(22)连接淘汰策略支持基于SPI扩展最早连接淘汰策略、最晚连接淘汰策略、先进先出连接淘汰策略、使用次数最少连接淘汰策略、最近未被使用连接淘汰策略、随机连接淘汰策略和拒绝连接淘汰策略。

(23)框架支持数据缓冲功能,并且服务提供者和服务消费者整合了数据缓冲功能。

(24)服务提供者与服务消费者都具备服务容错的能力,服务提供者与服务消费者之间的容错机制主要是通过自定义的网络传输协议中,消息有中的状态来决定的,如果状态为正常,也就是成功状态,则服务消费者会认为服务调用成功,则正常返回结果。如果状态为失败,则服务消费者会认为服务调用失败,发生了异常,则服务消费者会进行容错处理。此时,如果配置了容错处理类,则服务消费者会自动调用容错处理类的方法,并返回结果。

(25)RPC框架会以SPI的形式支持限流接口和各种限流策略,并且服务提供者和服务消费者整合了服务限流策略。

(26)RPC框架支持基于计数器的限流策略、基于Seamphore的限流策略和基于Guava的限流策略,并且支持SPI扩展限流策略,在实际场景下可根据实际需要动态扩展限流策略。

(27)服务提供者和服务消费者超出限流上限时,会根据配置执行抛出异常、降级处理、继续执行等规则。

(28)RPC框架支持基于计数器的熔断策略。

# 四、实现

说了这么多,具体要怎么实现呢?

# 核心类实现关系

服务熔断基础模型的核心类关系如图116-2所示。

图116-2

# 查看完整文章

加入冰河技术 (opens new window)知识星球,解锁完整技术文章与完整代码