## 一、雪崩效应 在微服务架构中通常会有多个服务层调用,基础服务的故障可能会导致级联故障,进而造成整个系统不可用的情况,这种现象被称为服务雪崩效应。  ##### 1、发展步骤 **第1步:正常状态** - 所有服务(A, B, D)都健康运行,请求处理流畅。 **第2步:故障起源(服务B出现问题)** - **原因**:服务B所依赖的底层资源(如数据库)出现性能瓶颈(如慢查询)、宕机或网络延迟。 - **表现**:服务B处理请求的速度变慢,每个请求占用的线程/连接时间变长。 **第3步:资源耗尽(雪崩的导火索)** - 由于请求持续涌入,服务B的线程池(或数据库连接池)被这些“慢请求”逐渐占满。 - 新的请求到达服务B时,因没有可用资源而被拒绝(报错或超时)。**此时,服务B已近乎瘫痪。** **第4步:故障向上蔓延(波及服务A)** - 服务A在调用服务B时,需要等待其响应,因此服务A的工作线程也被大量“挂起”和占用。 - 这导致服务A的可用线程资源减少,处理能力下降。 **第5步:故障扩散(级联失败,真正的雪崩)** - 即使那些**不直接依赖服务B**的请求(比如服务A调用服务D的请求),也会因为服务A本身的资源耗尽而失败。 - **最终结果**:一个非关键服务(B)的故障,像雪崩一样层层向上和横向扩散,耗尽了整个系统的资源(如线程、连接),导致所有或大部分服务不可用,系统全面崩溃。 ##### 2、解决方案 1. **服务熔断:** - **类比:电路保险丝。** 当服务B的失败率超过阈值时,**熔断器**会“跳闸”,在一段时间内直接拒绝所有发往服务B的请求,而不是让请求去阻塞和耗尽资源。 - **在图中的效果**:服务A会快速失败,释放线程,保证自身不瘫痪,从而不影响服务D。 2. **服务降级:** - **类比:应急方案。** 当熔断发生或服务不可用时,提供一个备选方案。例如,查询用户信息失败时,返回一个默认用户或缓存中的旧数据,而不是直接报错。 3. **请求限流/流量控制:** - **类比:高峰期地铁限流。** 在服务入口控制每秒处理的请求数,超过限制的请求直接拒绝,确保系统不会被突发流量冲垮。 4. **超时控制:** - 为所有服务调用设置一个合理的超时时间,避免线程被无限期挂起。 5. **舱壁(服务)隔离:** - **类比:轮船的防水舱壁。** 将资源(如线程池)进行隔离。例如,为调用服务B和服务D分配独立的线程池。这样即使调用服务B的线程池耗尽,也不会影响调用服务D的请求。 ## 二、延迟和容错 CircuitBreaker旨在隔离对远程系统、服务和第三方库的访问点,停止级联故障,并在复杂的分布式系统中提供 resiliency(弹性)。 #### 1、核心机制 * **隔离**:通过隔离不同的服务依赖,限制任何一个依赖出现问题时消耗的资源。 * **熔断**:当某个服务的失败率达到阈值时,自动停止向其发送请求(熔断),快速失败。 * **降级**:当服务熔断、超时或失败时,提供备用的处理逻辑(降级),而不是直接抛出错误。 #### 2、工作流程 #### 3、使用方法 Spring Cloud `OpenFeign` 从 4.0 版本开始,熔断器功能需要单独引入依赖(如 Resilience4j 或 Spring Cloud Circuit Breaker)。 ##### 添加依赖 ```xml org.springframework.cloud spring-cloud-starter-circuitbreaker-resilience4j ``` Resilience4J 的实现有两个 starter,一个用于 Reactive (响应式)应用,一个用于非 Reactive 应用。 - `org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j` - 非 Reactive 应用。 - `org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j` - Reactive (响应式)应用。 ##### 修改配置 修改`消费者`的`application.yml`的内容,添加`Hystrix`相关配置 ```yml spring: cloud: openfeign: circuitbreaker: enabled: true #在feign中开启Circuit Breaker熔断机制 #resilience4j: # enabled: false #禁用 Resilience4J 的自动配置 ``` 老版本可以使用自带的`Hystrix` ```yml feign: hystrix: enabled: true #在feign中开启hystrix熔断机制 ``` ##### 实现Feign接口 创建FeignClient接口的实现类:`feign/impl/TestFeignClientCallBack.java` ```java import cn.doooog.consumer.feign.TestFeignClient; import cn.doooog.consumer.po.CommonResult; import org.springframework.stereotype.Component; @Component public class TestFeignClientCallBack implements TestFeignClient { @Override public CommonResult getUserById(Integer userId) { return CommonResult.failed(500, "服务繁忙,触发熔断"); } } ``` #### 修改`@FeignClient`注解 ```java import cn.doooog.consumer.feign.impl.TestFeignClientCallBack; import cn.doooog.consumer.po.CommonResult; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; // 指定失败后降级调用的类 @FeignClient(name = "provider", fallback = TestFeignClientCallBack.class) public interface TestFeignClient { @GetMapping("/user/id/{userId}") CommonResult getUserById(@PathVariable("userId") Integer userId); } ``` ## 三、熔断器的工作状态 熔断器有三个状态 `CLOSED` 、`OPEN` 、`HALF_OPEN`: - **关闭**:请求正常通过,熔断器会持续监控失败率。 - **打开**:当失败率(如:10秒内超过20次失败)达到阈值时,熔断器“跳闸”进入`打开`状态。**在此状态下,所有请求都会被立即拒绝并直接执行降级逻辑**,而不会真正发起远程调用。这给了后端服务恢复的时间。 - **半开**:经过一个设定的“睡眠窗口”(默认5秒)后,熔断器会进入`半开`状态,允许放行一个试探请求。如果该请求成功,则认为服务已恢复,熔断器置为`关闭`;如果失败,则重回`打开`状态。 ## 四、更改默认配置 为了给所有的CircuitBreakers(熔断器)提供一个默认的配置,创建一个 `Customizer` bean,它被传递给 `Resilience4JCircuitBreakerFactory` 或 `ReactiveResilience4JCircuitBreakerFactory`。`configureDefault` 方法可以用来提供一个默认配置。 ```java @Bean public Customizer defaultCustomizer() { return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id) .timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(4)).build()) .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults()) .build()); } ``` #### Reactive 示例 ```java @Bean public Customizer defaultCustomizer() { return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id) .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults()) .timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(4)).build()).build()); } ``` #### 其他配置 请参考官方文档[Spring Cloud Circuit Breaker 中文文档](https://springdoc.cn/spring-cloud-circuitbreaker/#配置-resilience4j-circuit-breakers) Loading... ## 一、雪崩效应 在微服务架构中通常会有多个服务层调用,基础服务的故障可能会导致级联故障,进而造成整个系统不可用的情况,这种现象被称为服务雪崩效应。  ##### 1、发展步骤 **第1步:正常状态** - 所有服务(A, B, D)都健康运行,请求处理流畅。 **第2步:故障起源(服务B出现问题)** - **原因**:服务B所依赖的底层资源(如数据库)出现性能瓶颈(如慢查询)、宕机或网络延迟。 - **表现**:服务B处理请求的速度变慢,每个请求占用的线程/连接时间变长。 **第3步:资源耗尽(雪崩的导火索)** - 由于请求持续涌入,服务B的线程池(或数据库连接池)被这些“慢请求”逐渐占满。 - 新的请求到达服务B时,因没有可用资源而被拒绝(报错或超时)。**此时,服务B已近乎瘫痪。** **第4步:故障向上蔓延(波及服务A)** - 服务A在调用服务B时,需要等待其响应,因此服务A的工作线程也被大量“挂起”和占用。 - 这导致服务A的可用线程资源减少,处理能力下降。 **第5步:故障扩散(级联失败,真正的雪崩)** - 即使那些**不直接依赖服务B**的请求(比如服务A调用服务D的请求),也会因为服务A本身的资源耗尽而失败。 - **最终结果**:一个非关键服务(B)的故障,像雪崩一样层层向上和横向扩散,耗尽了整个系统的资源(如线程、连接),导致所有或大部分服务不可用,系统全面崩溃。 ##### 2、解决方案 1. **服务熔断:** - **类比:电路保险丝。** 当服务B的失败率超过阈值时,**熔断器**会“跳闸”,在一段时间内直接拒绝所有发往服务B的请求,而不是让请求去阻塞和耗尽资源。 - **在图中的效果**:服务A会快速失败,释放线程,保证自身不瘫痪,从而不影响服务D。 2. **服务降级:** - **类比:应急方案。** 当熔断发生或服务不可用时,提供一个备选方案。例如,查询用户信息失败时,返回一个默认用户或缓存中的旧数据,而不是直接报错。 3. **请求限流/流量控制:** - **类比:高峰期地铁限流。** 在服务入口控制每秒处理的请求数,超过限制的请求直接拒绝,确保系统不会被突发流量冲垮。 4. **超时控制:** - 为所有服务调用设置一个合理的超时时间,避免线程被无限期挂起。 5. **舱壁(服务)隔离:** - **类比:轮船的防水舱壁。** 将资源(如线程池)进行隔离。例如,为调用服务B和服务D分配独立的线程池。这样即使调用服务B的线程池耗尽,也不会影响调用服务D的请求。 ## 二、延迟和容错 CircuitBreaker旨在隔离对远程系统、服务和第三方库的访问点,停止级联故障,并在复杂的分布式系统中提供 resiliency(弹性)。 #### 1、核心机制 * **隔离**:通过隔离不同的服务依赖,限制任何一个依赖出现问题时消耗的资源。 * **熔断**:当某个服务的失败率达到阈值时,自动停止向其发送请求(熔断),快速失败。 * **降级**:当服务熔断、超时或失败时,提供备用的处理逻辑(降级),而不是直接抛出错误。 #### 2、工作流程 <img src="https://pic.soki.me/file/piclist/image-20251209154420527-1765266261310.png" alt="image-20251209154420527" style="zoom: 25%;" style=""> #### 3、使用方法 Spring Cloud `OpenFeign` 从 4.0 版本开始,熔断器功能需要单独引入依赖(如 Resilience4j 或 Spring Cloud Circuit Breaker)。 ##### 添加依赖 ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId> </dependency> ``` Resilience4J 的实现有两个 starter,一个用于 Reactive (响应式)应用,一个用于非 Reactive 应用。 - `org.springframework.cloud:spring-cloud-starter-circuitbreaker-resilience4j` - 非 Reactive 应用。 - `org.springframework.cloud:spring-cloud-starter-circuitbreaker-reactor-resilience4j` - Reactive (响应式)应用。 ##### 修改配置 修改`消费者`的`application.yml`的内容,添加`Hystrix`相关配置 ```yml spring: cloud: openfeign: circuitbreaker: enabled: true #在feign中开启Circuit Breaker熔断机制 #resilience4j: # enabled: false #禁用 Resilience4J 的自动配置 ``` 老版本可以使用自带的`Hystrix` ```yml feign: hystrix: enabled: true #在feign中开启hystrix熔断机制 ``` ##### 实现Feign接口 创建FeignClient接口的实现类:`feign/impl/TestFeignClientCallBack.java` ```java import cn.doooog.consumer.feign.TestFeignClient; import cn.doooog.consumer.po.CommonResult; import org.springframework.stereotype.Component; @Component public class TestFeignClientCallBack implements TestFeignClient { @Override public CommonResult getUserById(Integer userId) { return CommonResult.failed(500, "服务繁忙,触发熔断"); } } ``` #### 修改`@FeignClient`注解 ```java import cn.doooog.consumer.feign.impl.TestFeignClientCallBack; import cn.doooog.consumer.po.CommonResult; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; // 指定失败后降级调用的类 @FeignClient(name = "provider", fallback = TestFeignClientCallBack.class) public interface TestFeignClient { @GetMapping("/user/id/{userId}") CommonResult getUserById(@PathVariable("userId") Integer userId); } ``` ## 三、熔断器的工作状态 熔断器有三个状态 `CLOSED` 、`OPEN` 、`HALF_OPEN`: - **关闭**:请求正常通过,熔断器会持续监控失败率。 - **打开**:当失败率(如:10秒内超过20次失败)达到阈值时,熔断器“跳闸”进入`打开`状态。**在此状态下,所有请求都会被立即拒绝并直接执行降级逻辑**,而不会真正发起远程调用。这给了后端服务恢复的时间。 - **半开**:经过一个设定的“睡眠窗口”(默认5秒)后,熔断器会进入`半开`状态,允许放行一个试探请求。如果该请求成功,则认为服务已恢复,熔断器置为`关闭`;如果失败,则重回`打开`状态。 <img src="https://pic.soki.me/file/piclist/image-20251209162228483-1765268549096.png" alt="image-20251209162228483" style="zoom: 33%;" style=""> ## 四、更改默认配置 为了给所有的CircuitBreakers(熔断器)提供一个默认的配置,创建一个 `Customizer` bean,它被传递给 `Resilience4JCircuitBreakerFactory` 或 `ReactiveResilience4JCircuitBreakerFactory`。`configureDefault` 方法可以用来提供一个默认配置。 ```java @Bean public Customizer<Resilience4JCircuitBreakerFactory> defaultCustomizer() { return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id) .timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(4)).build()) .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults()) .build()); } ``` #### Reactive 示例 ```java @Bean public Customizer<ReactiveResilience4JCircuitBreakerFactory> defaultCustomizer() { return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id) .circuitBreakerConfig(CircuitBreakerConfig.ofDefaults()) .timeLimiterConfig(TimeLimiterConfig.custom().timeoutDuration(Duration.ofSeconds(4)).build()).build()); } ``` #### 其他配置 请参考官方文档[Spring Cloud Circuit Breaker 中文文档](https://springdoc.cn/spring-cloud-circuitbreaker/#配置-resilience4j-circuit-breakers) 最后修改:2025 年 12 月 09 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 👆请简单粗暴地爱我。