SpringCloud(七):Ribbon、Feign、Zuul的Fallback回退机制比较

概览

Ribbon Feign Zuul
使用的是@HystrixCommand注解,其实就是一个api 针对一个类,使用的是fallback属性 针对一个或多个微服务

Ribbon的Fallback机制

==使用的是@HystrixCommand注解,其实就是一个api ;==

如下:

@HystrixCommand(fallbackMethod = "defaultStores")
这个注解是通用的,不一定是Ribbon才用;

如何使用:

1
2
3
4
5
6
7
8
9
10
11
12
@Component
public class StoreIntegration {

@HystrixCommand(fallbackMethod = "defaultStores")
public Object getStores(Map<String, Object> parameters) {
//do stuff that might fail
}

public Object defaultStores(Map<String, Object> parameters) {
return /* something useful */;
}
}

如果要让某些线程本地上下文传播到@HystrixCommand,则默认声明不起作用,因为它在线程池中执行该命令(可能造成超时)。 通过配置或直接在注释中切换Hystrix以使用与调用者相同的线程,方法是要求它使用不同的“隔离策略”。

以下示例演示如何在注释中设置线程:

1
2
3
4
5
6
@HystrixCommand(fallbackMethod = "stubMyService",
commandProperties = {
@HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE")
}
)
...

@HystrixCommand由名为“javanica”的Netflix contrib库提供。 Spring Cloud在连接到Hystrix断路器的代理中自动包装带有该注释的Spring bean。 断路器计算何时打开和关闭电路以及在发生故障时应采取的措施。

See here for more details. See the Hystrix wiki for details on the properties available.

Feign的Fallback机制

==针对一个类,使用的是fallback属性==

如下:

  • 第一种fallback形式:@FeignClient(name = "hello", fallback = HystrixClientFallback.class)

    • 代码示例:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
         @FeignClient(name = "microservice-provider-user", fallback = HystrixClientFallback.class)
      public interface UserFeignClient {
      @RequestMapping(method = RequestMethod.GET, value = "/user/{id}", consumes = "application/json")
      public User findById(@PathVariable("id") Long id);
      }


      static class HystrixClientFallback implements UserFeignClient {
      @Override
      public User findById(Long id) {
      User user = new User();
      user.setId(1L);
      return user;
      }
      }
  • 第二种:fallbackFactory形式@FeignClient(name = "microservice-provider-user", /*fallback = HystrixClientFallback.class, */ fallbackFactory = HystrixClientFallbackFactory.class)

    • 代码示例:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      @FeignClient(name = "microservice-provider-user", /*fallback = HystrixClientFallback.class, */ fallbackFactory = HystrixClientFallbackFactory.class)
      public interface UserFeignClient {
      @RequestMapping(method = RequestMethod.GET, value = "/user/{id}", consumes = "application/json")
      public User findById(@PathVariable("id") Long id);
      }


      @Component
      static class HystrixClientFallbackFactory implements FallbackFactory<UserFeignClient> {

      private static Logger LOGGER = LoggerFactory.getLogger(HystrixClientFallbackFactory.class);

      @Override
      public UserFeignClient create(Throwable cause) {
      //打印日志
      HystrixClientFallbackFactory.LOGGER.info("fallback; reason was: " + cause.getMessage());

      return new UserFeignClient() {
      @Override
      public User findById(Long id) {
      User user = new User();
      user.setId(-1L);
      user.setUsername("我是HystrixClientFallbackFactory");

      return user;
      }
      };
      }

      }

Zuul的Fallback机制

==针对一个微服务==

如下:

Zuul的Fallback回退机制