在FeignClient中,我们通过制定fallback,可以在服务不可用时自动调用fallback制定的处理方法。
但如果如果希望同时知道发生回退的原因呢?
可以使用fallbackFactory属性。
下面以microservice-springcloud-movie-feign-with-hystrix模块来说明。
1.定义一个实现FallbackFactory的类
@Component
public class UserFeignClientHystrixFallbackFactory implements FallbackFactory<UserFeignClient>
{
private Logger logger = LoggerFactory.getLogger(UserFeignClientHystrixFallbackFactory.class);
@Override
public UserFeignClient create(Throwable throwable)
{
logger.error("fallback reason:{}",throwable.getMessage());
return new UserFeignClient()
{
@Override
public User findUserById(Long userId)
{
User user = new User();
user.setId(-1L);
return user;
}
};
}
}
如上,在发生回退时使用logger记录了回退的原因(异常),并返回了一个UserFeignClient,该实例重写了findUserById方法。
达到的效果就是在发生回退时,先打印回退原因,然后返回下面自定义的处理。
2.FeignClient类指定fallbackFactory属性。
// 不要同时使用fallback和fallbackFactory
@FeignClient(name = "microservice-springcloud-user"/*,fallback = UserHystrixClientFallback.class*/,fallbackFactory = UserFeignClientHystrixFallbackFactory.class)
public interface UserFeignClient {
@RequestMapping(value = "/sample/{userId}", method = RequestMethod.GET)
User findUserById(@PathVariable("userId") Long userId);
}
测试
1.启动Eureka Server;
2.启动user服务;
3.启动microservice-springcloud-movie-feign-with-hystrix。
浏览器访问/user/1,访问正常
关闭user服务,再次访问/user/1
可以看到,返回的是我们fallbackFactory中指定的处理方法的结果。
看控制台打印的异常信息是null
但实际上错误原因是TimeoutException,如下
现在多次刷新/user/1,使断路器打开。然后再次访问/user/1
现在回退的原因是断路器打开了。
注意
fallback和fallbackFactory只能指定一个,如果2个都指定了,生效的是fallback。