Feign的回退
因为Feign以接口的形式工作,没有方法体。Spring Cloud默认为Feign整合了Hystrix,只要Hystrix在项目的classpath中,Feign默认就会用断路器包裹所有的方法。
首先我们复制项目micro-service-consumer-movie-feign,修改为micro-service-consumer-movie-feign-hystrix-fallback。
我们修改之前编写的UserFeignClient接口的@FeignClient注解,使用该注解的fallback属性指定回退类。
@Component
@FeignClient(name="microservice-provider", fallback = FeignClientFallback.class)
public interface UserFeignClient {
/**
* 注意不要用组合注解
* @param id
* @return
*/
@RequestMapping(value = "/user/simple/{id}", method = RequestMethod.GET)
User findById(@PathVariable("id") Long id);
@RequestMapping(value = "/user/user", method = RequestMethod.POST)
User postUser(@RequestBody User user);
/**
* GET请求传参为对象不会报错
* @param user
* @return
*/
@RequestMapping(value = "/user/user", method = RequestMethod.GET)
User getUser(User user);
}
然后编写FeignClientFallback类,该类需要实现UserFeignClient接口,由代码可知,只许使用@FeignClient注解的fallback属性,就可为指定名称的Feign客户端添加回退。
@Component
public class FeignClientFallback implements UserFeignClient {
@Override
public User findById(Long id) {
User user = new User();
user.setId(-1L);
user.setName("默认用户");
return user;
}
@Override
public User postUser(User user) {
return null;
}
@Override
public User getUser(User user) {
return null;
}
}
通过Fallback Factory检查回退原因
在很多场景下需要了解回退的原因,此时使用注解@FeignClient的fallbackFactory属性,以下代码为Feign打印回退日志。
复制项目micro-service-consumer-movie-feign修改为micro-service-consumer-movie-feign-hystrix-fallback-factory。需要修改UserFeignClient,在@FeignClient注解上添加fallbackFactory属性。
@Component
@FeignClient(name="microservice-provider", fallbackFactory = FeignClientFallbackFactory.class)
public interface UserFeignClient {
/**
* 注意不要用组合注解
* @param id
* @return
*/
@RequestMapping(value = "/user/simple/{id}", method = RequestMethod.GET)
User findById(@PathVariable("id") Long id);
@RequestMapping(value = "/user/user", method = RequestMethod.POST)
User postUser(@RequestBody User user);
/**
* GET请求传参为对象不会报错
* @param user
* @return
*/
@RequestMapping(value = "/user/user", method = RequestMethod.GET)
User getUser(User user);
}
创建FeignClientFallbackFactory类,并且实现FallbackFactory接口,并覆写create方法。
@Component
public class FeignClientFallbackFactory implements FallbackFactory<UserFeignClient> {
private static Logger logger = LoggerFactory.getLogger(FeignClientFallbackFactory.class);
@Override
public UserFeignClient create(Throwable throwable) {
return new UserFeignClient() {
@Override
public User findById(Long id) {
logger.info("fallback; reason was :", throwable);
User user = new User();
user.setId(-1L);
user.setName("默认用户");
return user;
}
@Override
public User postUser(User user) {
return null;
}
@Override
public User getUser(User user) {
return null;
}
};
}
}
当Feign发生回退时就会打印日志。
请求http://localhost:8028/movie/1结果为:
Feign禁用Hystrix
Spring Cloud只要Hystrix在项目的classpath中,Feign就会使用断路器包裹Feign客户端的所有方法。只需要借助Feign的自定义配置,就可以为指定名称的Feign客户端禁用Hystrix。
/**
* Description: 禁用feign的Hystrix
* Author:
* Date:2019/2/19
*/
@Configuration
public class FeignDisableHystrixConfiguration {
@Bean
@Scope("prototype")
public Feign.Builder feignBuilder() {
return Feign.builder();
}
}
禁用Hystrix,只需要在@FeignClient注解中指定该配置即可。
@Component
@FeignClient(name="micro-service-provider", configuration = FeignDisableHystrixConfiguration.class)
public interface UserFeignClient {
/**
* 注意不要用组合注解
* @param id
* @return
*/
@RequestMapping(value = "/user/simple/{id}", method = RequestMethod.GET)
User findById(@PathVariable("id") Long id);
@RequestMapping(value = "/user/user", method = RequestMethod.POST)
User postUser(@RequestBody User user);
/**
* GET请求传参为对象不会报错
* @param user
* @return
*/
@RequestMapping(value = "/user/user", method = RequestMethod.GET)
User getUser(User user);
}
如果想要全局禁用Hystrix, 只需在application.yml文件中配置即可:
feign:
hystrix:
enabled: false