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]
從異常信息可以看出發生了超時