一、概述
1.1、基礎【示例一】
如果Hystrix在類路徑上並且feign.hystrix.enabled = true,Feign將用斷路器包裝所有方法。還可以返回com.netflix.hystrix.HystrixCommand。這可讓您使用響應模式(調用.toObservable()或.observe()或異步使用(調用.queue())。
要以每個客戶端為基礎禁用Hystrix支持,請創建一個具有“prototype”范圍。
在Spring Cloud Dalston發布之前,如果Hystrix在類路徑上,Feign默認情況下會將所有方法封裝在斷路器中。 Spring Cloud Dalston改變了這種默認行為,以支持選擇加入方式。
@Configuration public class FooConfiguration { @Bean @Scope("prototype") public Feign.Builder feignBuilder() { return Feign.builder(); } }
1.2、Fallbacks【示例一、示例二】
Hystrix支持回退的概念:當電路斷開或出現錯誤時執行的默認代碼路徑。要為給定的@FeignClient啟用回退,請將fallback屬性設置為實現回退的類名稱。您還需要將您的實現聲明為Spring bean。
@FeignClient(name = "hello", fallback = HystrixClientFallback.class) protected interface HystrixClient { @RequestMapping(method = RequestMethod.GET, value = "/hello") Hello iFailSometimes(); } static class HystrixClientFallback implements HystrixClient { @Override public Hello iFailSometimes() { return new Hello("fallback"); } }
1.3、回退觸發器的原因fallbackFactory屬性[示例三]
如果需要訪問作為回退觸發器的原因,則可以使用@FeignClient中的fallbackFactory屬性。
為指定的客戶端接口定義一個回退工廠。回退工廠必須產生回退類的實例,這些實例實現由FeignClient注釋的接口。
如果同時設置fallback和fallbackfactory不可以有沖突,fallback生效,fallbackfactory不能使用,fallbackFactory 是fallback的一個升級版,注釋fallback設置即可
@FeignClient(name = "hello", fallbackFactory = HystrixClientFallbackFactory.class) protected interface HystrixClient { @RequestMapping(method = RequestMethod.GET, value = "/hello") Hello iFailSometimes(); } @Component static class HystrixClientFallbackFactory implements FallbackFactory<HystrixClient> { @Override public HystrixClient create(Throwable cause) { return new HystrixClient() { @Override public Hello iFailSometimes() { return new Hello("fallback; reason was: " + cause.getMessage()); } }; } }
查看FallbackFactory

public interface FallbackFactory<T> { /** * Returns an instance of the fallback appropriate for the given cause * * @param cause corresponds to {@link com.netflix.hystrix.AbstractCommand#getExecutionException()} * often, but not always an instance of {@link FeignException}. */ T create(Throwable cause); /** Returns a constant fallback after logging the cause to FINE level. */ final class Default<T> implements FallbackFactory<T> { // jul to not add a dependency final Logger logger; final T constant; public Default(T constant) { this(constant, Logger.getLogger(Default.class.getName())); } Default(T constant, Logger logger) { this.constant = checkNotNull(constant, "fallback"); this.logger = checkNotNull(logger, "logger"); } @Override public T create(Throwable cause) { if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "fallback due to: " + cause.getMessage(), cause); } return constant; } @Override public String toString() { return constant.toString(); } } }
注意事項:在Feign中實施回退以及Hystrix回退的工作方式存在限制。目前,com.netflix.hystrix.HystrixCommand和rx.Observable的方法不支持回退。
二、示例區
示例一、feign使用hystrix
示例參看:https://github.com/bjlhx15/spring-cloud/tree/master/microservice-comsumer-movie-feign-with-hystrix
1、增加引用
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
2、增加配置啟用
feign.hystrix.enabled=true
3、啟動類增加注解
@EnableCircuitBreaker
4、增加UserFeignClient業務接口,並配置fallback
@FeignClient(name = "microservice-provider-user", fallback = HystrixClientFallback.class) public interface UserFeignClient { // @GetMapping("/sample/{id}") @RequestMapping(method = RequestMethod.GET, value = "/sample/{id}") public User findById(@PathVariable("id") Long id); }
5、增加HystrixClientFallback類
@Component public class HystrixClientFallback implements UserFeignClient { @Override public User findById(Long id) { User user = new User(); user.setId(0L); return user; } }
示例二、如何禁用單個FegionClient的Hystrix的支持
1、設置一遍如同上面
2、新增一個業務接口FeignClient2
@FeignClient(name = "xxxx", url = "http://localhost:8761/", configuration = Configuration2.class,fallback = FeignClient2Fallback.class) public interface FeignClient2 { @RequestMapping(value = "/eureka/apps/{serviceName}") public String findServiceInfoFromEurekaByServiceName(@PathVariable("serviceName") String serviceName); }
3、使用fallback
@Component public class FeignClient2Fallback implements FeignClient2 { @Override public String findServiceInfoFromEurekaByServiceName(String serviceName) { return "haha"; } }
4、使用的配置類
@Configuration public class Configuration2 { @Bean public BasicAuthRequestInterceptor basicAuthRequestInterceptor() { return new BasicAuthRequestInterceptor("user", "a123"); } @Bean @Scope("prototype") public Feign.Builder feignBuilder() { return Feign.builder(); } }
可以看到這里主要增加了feignBuilder創建
示例三、 回退觸發器的原因fallbackFactory屬性
參考代碼:
1、基本配置略
2、配置UserFeignClient
@FeignClient(name = "microservice-provider-user", fallbackFactory = HystrixClientFallbackFactory.class) public interface UserFeignClient { // @GetMapping("/sample/{id}") @RequestMapping(method = RequestMethod.GET, value = "/sample/{id}") public User findById(@PathVariable("id") Long id); }
注意:配置了fallbackFactory ,如果同時設置fallback和fallbackfactory不可以有沖突,只能設置一個,fallbackFactory 是fallback的一個升級版
3、fallbackFactory 的類設置HystrixClientFallbackFactory
@Component public class HystrixClientFallbackFactory implements FallbackFactory<UserFeignClient> { private static final Logger logger = LoggerFactory.getLogger(HystrixClientFallbackFactory.class); @Override public UserFeignClient create(Throwable arg0) { HystrixClientFallbackFactory.logger.info("fallback reason was:{}", arg0.getMessage()); return new UserFeignClientWithFactory() { @Override public User findById(Long id) { User user = new User(); user.setId(-1L); return user; } }; } }
4、UserFeignClientWithFactory設置
public interface UserFeignClientWithFactory extends UserFeignClient { }