FeignClient Hystrix超时重试降级讲了Hystrix和feign各自的超时,重试,降级策略。然后Hystrix其实已经不再维护了,社区推荐Resilience4j,阿里有一个开源的sentinel也可以做到熔断限流等功能。网上有一个表格图片,对比了三者的不同。
我自己在实际使用中的情况是,服务间调用使用Feign,没有用其他RPC框架,然后想做熔断策略,又不想用Hystrix,毕竟不维护了,所以在考虑Resilience4j 和sentinel。然后对比了之后发现sentinel可以无缝切换Hystrix+Feign。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>0.2.1.RELEASE</version>
</dependency>
@Bean
@Scope("prototype")
@ConditionalOnMissingBean
@ConditionalOnProperty(name = "feign.sentinel.enabled", matchIfMissing = true)
public Feign.Builder sentinelHystrixBuilder() {
return SentinelFeign.builder();
}
但是我们进入SentinelFeign里面会发现,这种配置只实现了基础的fallback,如果想做到限流,熔断,还需要配合其dashboard,但是现实情况是,我们的熔断并不怎么变化,只是一种以防万一,不需要动态配置。那么虽然dashboard很轻量,还是有点不合适。
注:这里说的sentinel只能用dashboard做熔断,限流配置是因为使用SentinelFeign,实际上的sentinel是可以使用代码写死规则的
然后考虑Resilience4j,这个网上搜了一下,没啥实际使用的感觉,至少在我这个实用主义来看,那些demo代码都用不上,然后看了github,有个Resilience4j-feign,然后我就试用了一下。
那么果然可以在代码里配置熔断的策略,可以配置
@Bean
@Scope("prototype")
@ConditionalOnMissingBean
public Resilience4jFeign.Builder feignResilience4jBuilder() {
CircuitBreaker circuitBreaker = CircuitBreaker.ofDefaults("backendName");
RateLimiter rateLimiter = RateLimiter.ofDefaults("backendName");
FeignDecorators decorators = FeignDecorators.builder()
.withRateLimiter(rateLimiter)
.withCircuitBreaker(circuitBreaker)
.build();
return Resilience4jFeign.builder(decorators);
}
那么就想更进一步,能不能利用上次FeignClient Hystrix超时重试降级中的MyHystrixAnno 注解,增加一些自定义的配置呢?至少git上官方代码不行了。然后就对比学习了一下HystrixFeign,SentinelFeign,Resilience4jFeign,发现了一些共同点,然后自己改造了一波,记录如下。
另外:Resilience4jFeign里很多类的访问级别是包内,或者是final class的,所以我改造的时候只能copy出来改造。
使用Resilience4j-feign需要添加如下maven配置
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-feign</artifactId>
<version>1.1.0</version>
</dependency>
1、从FeignClientFactoryBean#feign方法来看,feign的一些设置参数可以通过Builder来设置,这一点可以从以上三个框架里看出来
HystrixFeign
public static final class Builder extends Feign.Builder
SentinelFeign
public static final class Builder extends feign.Feign.Builder implements ApplicationContextAware
Resilience4jFeign
@Bean
@Scope("prototype")
@ConditionalOnMissingBean