# 熔断降级 [English](../en/degrade.md) | **简体中文** | [繁體中文](../tw/degrade.md) | [日本語](../ja/degrade.md) | [한국어](../ko/degrade.md) | [Español](../es/degrade.md) | [Türkçe](../tr/degrade.md) | [Русский](../ru/degrade.md) 熔断降级默认关闭,当前支持 **Sentinel** 和 **Resilience4j** 两种实现。 ```yaml retrofit: degrade: # 熔断降级类型,默认 none 表示不启用 degrade-type: sentinel ``` ## Sentinel ### 引入依赖 手动引入 Sentinel 依赖: ```xml com.alibaba.csp sentinel-core 1.8.6 ``` ### 声明式熔断 配置 `degrade-type=sentinel` 开启,然后在相关接口或者方法上声明 `@SentinelDegrade` 注解: ```java @Timeout(connectTimeoutMs = 1, readTimeoutMs = 1, writeTimeoutMs = 1) @RetrofitClient(baseUrl = "${test.baseUrl}", fallback = SentinelFallbackUserService.class) @SentinelDegrade(rules = { @SentinelDegradeRule(grade = 0, count = 100, timeWindow = 4), @SentinelDegradeRule(grade = 1, count = 0.01, timeWindow = 3) }) public interface SentinelUserService { @POST("getName") String getName(@Query("id") Long id); @GET("getUser") @SentinelDegrade(rules = {@SentinelDegradeRule(grade = 2, count = 1, timeWindow = 6)}) User getUser(@Query("id") Long id); } ``` ### 全局 Sentinel 熔断降级 ```yaml retrofit: global-sentinel-degrade: enable: true rules: # 降级策略(0:平均响应时间;1:异常比例;2:异常数量) - grade: 0 # 各降级策略对应的阈值。平均响应时间(ms),异常比例(0-1),异常数量(1-N) count: 1000 # 熔断时长,单位为 s time-window: 5 # (在有效统计时间范围内)能够触发熔断的最小请求数 min-request-amount: 5 # RT 模式下慢请求率的阈值 slow-ratio-threshold: 1.0 # 时间间隔统计持续时间,单位为毫秒 stat-interval-ms: 1000 ``` ## Resilience4j ### 引入依赖 手动引入 Resilience4j 依赖: ```xml io.github.resilience4j resilience4j-circuitbreaker 1.7.1 ``` ### 注册熔断配置 实现 `CircuitBreakerConfigRegistrar` 接口,注册 `CircuitBreakerConfig`: ```java @Component public class CustomCircuitBreakerConfigRegistrar implements CircuitBreakerConfigRegistrar { @Override public void register(CircuitBreakerConfigRegistry registry) { // 替换默认的 CircuitBreakerConfig registry.register(Constants.DEFAULT_CIRCUIT_BREAKER_CONFIG, CircuitBreakerConfig.ofDefaults()); // 注册其他的 CircuitBreakerConfig registry.register("testCircuitBreakerConfig", CircuitBreakerConfig.custom() .slidingWindowType(CircuitBreakerConfig.SlidingWindowType.TIME_BASED) .failureRateThreshold(20) .minimumNumberOfCalls(5) .permittedNumberOfCallsInHalfOpenState(5) .build()); } } ``` ### 声明式熔断 配置 `degrade-type=resilience4j` 开启,然后在相关接口或者方法上声明 `@Resilience4jDegrade`: ```java @Timeout(connectTimeoutMs = 1, readTimeoutMs = 1, writeTimeoutMs = 1) @RetrofitClient(baseUrl = "${test.baseUrl}", fallbackFactory = Resilience4jFallbackFactory.class) @Resilience4jDegrade(circuitBreakerConfigName = "testCircuitBreakerConfig") public interface Resilience4jUserService { @POST("getName") String getName(@Query("id") Long id); @GET("getUser") @Resilience4jDegrade(enable = false) User getUser(@Query("id") Long id); } ``` ### 全局 Resilience4j 熔断降级 ```yaml retrofit: degrade: degrade-type: resilience4j global-resilience4j-degrade: enable: true # 根据该名称从 CircuitBreakerConfigRegistry 获取 CircuitBreakerConfig,作为全局熔断配置 circuit-breaker-config-name: defaultCircuitBreakerConfig ``` 通过 `circuitBreakerConfigName` 指定 `CircuitBreakerConfig`,包括 `retrofit.degrade.global-resilience4j-degrade.circuit-breaker-config-name` 或者 `@Resilience4jDegrade.circuitBreakerConfigName`。 ## 扩展熔断降级 如果需要使用其他熔断降级实现,继承 `BaseRetrofitDegrade`,并将其配置成 Spring Bean。 ## Fallback 与 FallbackFactory 如果 `@RetrofitClient` 不设置 `fallback` 或者 `fallbackFactory`,当触发熔断时会直接抛出 `RetrofitBlockException` 异常。用户可以通过设置 `fallback` 或者 `fallbackFactory` 来定制熔断时的方法返回值。 > 注意:`fallback` 类必须是当前接口的实现类,`fallbackFactory` 必须是 `FallbackFactory` 实现类,泛型参数类型为当前接口类型。另外,`fallback` 和 `fallbackFactory` 实例必须配置成 Spring Bean。 `fallbackFactory` 相对于 `fallback`,主要差别在于能够感知每次熔断的异常原因(cause)。 ### Fallback 示例 ```java @Slf4j @Service public class HttpDegradeFallback implements HttpDegradeApi { @Override public Result test() { Result fallback = new Result<>(); fallback.setCode(100) .setMsg("fallback") .setBody(1000000); return fallback; } } ``` ### FallbackFactory 示例 ```java @Slf4j @Service public class HttpDegradeFallbackFactory implements FallbackFactory { @Override public HttpDegradeApi create(Throwable cause) { log.error("触发熔断了! ", cause.getMessage(), cause); return new HttpDegradeApi() { @Override public Result test() { Result fallback = new Result<>(); fallback.setCode(100) .setMsg("fallback") .setBody(1000000); return fallback; } }; } } ``` --- [上一节:拦截器](interceptor.md) | [下一节:错误解码器](error-decoder.md)