https://www.cnblogs.com/qq931399960/p/15846408.html
根据上述操作,虽然发生错误后,可以执行fallback,但具体的错误信息后端没有打印,具体的错误信息有时候很重要,可以帮助我们来定位错误的根本原因
根据Spring Cloud OpenFeign官方文档"1.6. Feign Spring Cloud CircuitBreaker Fallbacks",实现该功能也很简单
在本例中,将之前使用的feignclient注解的属性fallback改为使用fallbackFactory,并且callback实现类改为ConsumerServiceCallbackFactory
feign接口
package com.demo.service; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import com.demo.entity.ResultEntity; import com.demo.service.callback.ConsumerServiceCallbackFactory; @FeignClient(name = "SERVICE-PROVIDER", fallbackFactory = ConsumerServiceCallbackFactory.class) public interface ConsumerService { /** * 此处不能返回Object,要么返回String,要么返回存在get set方法的实体对象或者map * @param id * @return */ @RequestMapping("/getData/{id}") ResultEntity getData(@PathVariable String id); }
fallback factory
package com.demo.service.callback; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.openfeign.FallbackFactory; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.PathVariable; import com.demo.entity.ResultEntity; import com.demo.service.ConsumerService; @Component public class ConsumerServiceCallbackFactory implements FallbackFactory<ConsumerServiceCallBack>{ private Logger logger = LoggerFactory.getLogger(ConsumerServiceCallbackFactory.class); @Override public ConsumerServiceCallBack create(Throwable e) { logger.error("",e); return new ConsumerServiceCallBack(); } } class ConsumerServiceCallBack implements ConsumerService{ private Logger logger = LoggerFactory.getLogger(ConsumerServiceCallBack.class); @Override public ResultEntity getData(@PathVariable String id) { logger.error("call back id: {}", id); return new ResultEntity(false, "error"); } }
测试
将服务提供者服务线程休眠一段时间,模拟出read timeout,重启服务提供者合并服务消费者,再次访问:http://127.0.0.1:8081/getData/10
浏览器显示
后端打印出异常信息
2022-01-26 15:05:48.239 ERROR 193180 --- [nio-8081-exec-4] c.d.s.c.ConsumerServiceCallbackFactory : java.util.concurrent.TimeoutException: TimeLimiter 'ConsumerService#getData(String)' recorded a timeout exception. at java.util.concurrent.FutureTask.get(Unknown Source) ~[na:1.8.0_172] at io.github.resilience4j.timelimiter.internal.TimeLimiterImpl.lambda$decorateFutureSupplier$0(TimeLimiterImpl.java:46) ~[resilience4j-timelimiter-1.7.0.jar:1.7.0] at io.github.resilience4j.circuitbreaker.CircuitBreaker.lambda$decorateCallable$3(CircuitBreaker.java:171) ~[resilience4j-circuitbreaker-1.7.0.jar:1.7.0] at io.vavr.control.Try.of(Try.java:75) ~[vavr-0.10.2.jar:na]
从异常信息可以看出发生了超时