SpringCloud Feign 全局Fallback的另一种实现方式(SpringBoot3.4+)


前言

之前在SpringBoot2.7+中实现 全局Fallback方式较为复杂,且是从Feign入手,现在从断路器入手,通过捕获异常方式实现。

注意:这里基于SpringBoot3.4实现的,如果是2.7那么又会复杂一点,原因是内置的Resilience4JCircuitBreakerFactory实现的接口未返回接口CircuitBreaker而是实现Resilience4JCircuitBreaker,在3.4版本已修正为接口CircuitBreaker。


一、定制Fegin

参考之前的实现

二、定制断路器

因为在未设置断路器时,会抛出NoFallbackAvailableException,所以就通过捕获NoFallbackAvailableException来实现全局Fallback

1.自定义断路器DefaultCircuitBreaker

class DefaultCircuitBreaker implements CircuitBreaker {

    private static final Logger log = LoggerFactory.getLogger(DefaultCircuitBreaker.class);

    private final CircuitBreaker circuitBreaker;

    DefaultCircuitBreaker(CircuitBreaker circuitBreaker) {
        this.circuitBreaker = circuitBreaker;
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> T run(Supplier<T> toRun, Function<Throwable, T> fallback) {
        try {
            return circuitBreaker.run(toRun, fallback);
        } catch (NoFallbackAvailableException e) {
            Throwable cause = e.getCause();
            String errorMessage = cause.getMessage();
            if (cause instanceof FeignException exception && !exception.contentUTF8().isEmpty()) {
                errorMessage = exception.contentUTF8();
            }
            log.error("Using DefaultFallback handle exception", cause);
            return (T) RestResp.error(ExceptionKeys.REMOTE_SERVICE_ERROR, errorMessage);
        }
    }

}

2.定义Resilience4JCircuitBreakerFactory bean来替换内置断路器

    @Bean
    Resilience4JCircuitBreakerFactory resilience4jCircuitBreakerFactory(CircuitBreakerRegistry circuitBreakerRegistry, TimeLimiterRegistry timeLimiterRegistry,
                                                                        @Autowired(required = false) Resilience4jBulkheadProvider bulkheadProvider,
                                                                        Resilience4JConfigurationProperties resilience4JConfigurationProperties) {
        return new Resilience4JCircuitBreakerFactory(circuitBreakerRegistry,
                timeLimiterRegistry, bulkheadProvider, resilience4JConfigurationProperties) {
            @Override
            public CircuitBreaker create(String id) {
                return new DefaultCircuitBreaker(super.create(id));
            }

            @Override
            public CircuitBreaker create(String id, String groupName) {
                return new DefaultCircuitBreaker(super.create(id, groupName));
            }
        };
    }

封装成Starter

  1. 创建一个自动配置类CircuitBreakerAutoConfiguration
@AutoConfiguration(before = Resilience4JAutoConfiguration.class)
@ConditionalOnClass(Resilience4JCircuitBreakerFactory.class)
public class CircuitBreakerAutoConfiguration {

    @Bean
    Resilience4JCircuitBreakerFactory resilience4jCircuitBreakerFactory(CircuitBreakerRegistry circuitBreakerRegistry, TimeLimiterRegistry timeLimiterRegistry,
                                                                        @Autowired(required = false) Resilience4jBulkheadProvider bulkheadProvider,
                                                                        Resilience4JConfigurationProperties resilience4JConfigurationProperties) {
        return new Resilience4JCircuitBreakerFactory(circuitBreakerRegistry,
                timeLimiterRegistry, bulkheadProvider, resilience4JConfigurationProperties) {
            @Override
            public CircuitBreaker create(String id) {
                return new DefaultCircuitBreaker(super.create(id));
            }

            @Override
            public CircuitBreaker create(String id, String groupName) {
                return new DefaultCircuitBreaker(super.create(id, groupName));
            }
        };
    }

}
  1. 将配置类添加到配置文件org.springframework.boot.autoconfigure.AutoConfiguration.imports中

  2. 如果需要配置一个开关来启用CircuitBreakerAutoConfiguration,也可以添加条件注解ConditionalOnProperty如下

@ConditionalOnProperty(prefix = "mcn.circuitbreaker", name = "default.enabled", havingValue = "true", matchIfMissing = true)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kse_music

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值