Spring Cloud Feign怎么实现自动降级
更新:HHH   时间:2023-1-7


这篇文章主要讲解了“Spring Cloud Feign怎么实现自动降级”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Spring Cloud Feign怎么实现自动降级”吧!

自动降级目的

在Spring Cloud 使用feign 的时候,需要明确指定fallback 策略,不然会提示错误。先来看默认的feign service 是要求怎么做的。feign service 定义一个 factory 和 fallback 的类

@FeignClient(value =ServiceNameConstants.UMPS_SERVICE, fallbackFactory =RemoteLogServiceFallbackFactory.class)

publicinterfaceRemoteLogService{}

但是我们大多数情况的feign 降级策略为了保证幂等都会很简单,输出错误日志即可。类似如下代码,在企业中开发非常不方便

@Slf4j

@Component

publicclassRemoteLogServiceFallbackImplimplementsRemoteLogService{

@Setter

privateThrowable cause;

@Override

public R<Boolean> saveLog(SysLog sysLog,Stringfrom){

log.error("feign 插入日志失败", cause);

returnnull;

}

}

自动降级效果

@FeignClient(value =ServiceNameConstants.UMPS_SERVICE)

publicinterfaceRemoteLogService{}

Feign Service 完成同样的降级错误输出

FeignClient 中无需定义无用的fallbackFactory

FallbackFactory 也无需注册到Spring 容器中

代码变化,去掉FeignClient 指定的降级工厂

代码变化,删除降级相关的代码

核心源码

1. 注入我们个性化后的Feign

@Configuration

@ConditionalOnClass({HystrixCommand.class,HystrixFeign.class})

protectedstaticclassHystrixFeignConfiguration{

@Bean

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

@ConditionalOnProperty("feign.hystrix.enabled")

publicFeign.Builder feignHystrixBuilder(FeignContext feignContext){

returnPigxHystrixFeign.builder(feignContext)

.decode404()

.errorDecoder(newPigxFeignErrorDecoder());

}

}

2. PigxHystrixFeign.target 方法是根据@FeignClient 注解生成代理类的过程,注意注释

@Override

public<T> T target(Target<T> target){

Class<T> targetType = target.type();

FeignClient feignClient =AnnotatedElementUtils.getMergedAnnotation(targetType,FeignClient.class);

String factoryName = feignClient.name();

SetterFactory setterFactoryBean =this.getOptional(factoryName, feignContext,SetterFactory.class);

if(setterFactoryBean !=null){

this.setterFactory(setterFactoryBean);

}

// 以下为获取降级策略代码,构建降级,这里去掉了降级非空的非空的校验

Class<?> fallback = feignClient.fallback();

if(fallback !=void.class){

return targetWithFallback(factoryName, feignContext, target,this, fallback);

}

Class<?> fallbackFactory = feignClient.fallbackFactory();

if(fallbackFactory !=void.class){

return targetWithFallbackFactory(factoryName, feignContext, target,this, fallbackFactory);

}

return build().newInstance(target);

}

3. 构建feign 客户端执行PigxHystrixInvocationHandler的增强

Feign build(@NullablefinalFallbackFactory<?> nullableFallbackFactory){

super.invocationHandlerFactory((target, dispatch)->

newPigxHystrixInvocationHandler(target, dispatch, setterFactory, nullableFallbackFactory));

super.contract(newHystrixDelegatingContract(contract));

returnsuper.build();

}

4. PigxHystrixInvocationHandler.getFallback() 获取降级策略

@Override

@Nullable

@SuppressWarnings("unchecked")

protectedObject getFallback(){

// 如果 @FeignClient 没有配置降级策略,使用动态代理创建一个

if(fallbackFactory ==null){

fallback =PigxFeignFallbackFactory.INSTANCE.create(target.type(), getExecutionException());

}else{

// 如果 @FeignClient配置降级策略,使用配置的

fallback = fallbackFactory.create(getExecutionException());

}

}

5. PigxFeignFallbackFactory.create 动态代理逻辑

public T create(finalClass<?> type,finalThrowable cause){

return(T) FALLBACK_MAP.computeIfAbsent(type, key ->{

Enhancer enhancer =newEnhancer();

enhancer.setSuperclass(key);

enhancer.setCallback(newPigxFeignFallbackMethod(type, cause));

return enhancer.create();

});

}

6. PigxFeignFallbackMethod.intercept, 默认的降级逻辑,输出降级方法信息和错误信息,并且把错误格式

publicObject intercept(Object o,Method method,Object[] objects,MethodProxy methodProxy){

log.error("Fallback class:[{}] method:[{}] message:[{}]",

type.getName(), method.getName(), cause.getMessage());

if(R.class== method.getReturnType()){

final R result = cause instanceofPigxFeignException?

((PigxFeignException) cause).getResult(): R.builder()

.code(CommonConstants.FAIL)

.msg(cause.getMessage()).build();

return result;

}

returnnull;

}

感谢各位的阅读,以上就是“Spring Cloud Feign怎么实现自动降级”的内容了,经过本文的学习后,相信大家对Spring Cloud Feign怎么实现自动降级这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是天达云,小编将为大家推送更多相关知识点的文章,欢迎关注!

返回web开发教程...