0503-Hystrix保護應用-feign的hystrix支持


一、概述

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();
    }
  }
}
View Code

注意事項:在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的支持

參考代碼:https://github.com/bjlhx15/spring-cloud/tree/master/microservice-comsumer-movie-feign-customizing-without-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 {

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM