当前位置: > > > SpringCloud - 服务容错保护组件Hystrix的使用详解3(定义服务降级)

SpringCloud - 服务容错保护组件Hystrix的使用详解3(定义服务降级)

三、定义服务降级

1,基本介绍

(1)当命令执行失败的时候,Hystrix 会进入 fallback 尝试回退处理,我们通常称该操作为“服务降级”。
(2)在服务降级逻辑中,我们需要实现一个通用的响应结果,并且该结果的处理逻辑应当是从缓存或是根据一些静态逻辑来获取,而不是依赖网络请求获取。
    如果一定要在降级逻辑中包含网络请求,那么该请求也必须被包装在 HystrixCommand 或是 HystrixObservableCommand 中(如下图),从而形成级联的降级策略,而最终的降级逻辑一定不是一个依赖网络请求的处理,而是一个能够稳定地返回结果的处理逻辑。

(3)如果我们没有为命令实现降级逻辑或者降级处理逻辑中抛出了异常,Hystrix 依然会返回一个 Observable 对象,但是它不会发射任何结果数据,而是通过 onError 方法通知命令立即中断请求,并通过 onError() 方法将引起命令失败的异常发送给调用者。
不过实现一个有可能失败的降级逻辑是一种非常糟糕的做法,我们应该在实现降级策略时尽可能避免失败的情况。

2,不需要实现降级逻辑的几种情况

    在实际使用时,我们需要为大多数执行过程中可能会失败的 Hystrix 命令实现服务降级逻辑,但是也有一些情况可以不去实现降级逻辑,比如:
  • 执行写操作的命令:当 Hystrix 命令是用来执行写操作而不是返回一些信息的时候,通常情况下这类操作的返回类型是 void 或是为空的 observable,实现服务降级的意义不是很大。当写入操作失败的时候,我们通常只需要通知调用者即可。
  • 执行批处理或离线计算的命令:当 Hystrix 命令是用来执行批处理程序生成一份报告或是进行任何类型的离线计算时,那么通常这些操作只需要将错误传播给调用者,然后让调用者稍后重试而不是发送给调用者一个静默的降级处理响应。

3,服务降级样例

(1)通过注解实现服务降级只需要使用 @HystrixCommand 注解中的 fallbackMethod 参数来指定具体的服务降级实现方法:
注意:具体的 Hystrix 命令与 fallback 实现函数需定义在同一个类中。同时由于在同一个类中,所以对 fallback 的访问修饰符没有特定的要求,定义为 privateprotectedpublic 均可。
public class UserService {
    @Autowired
    RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "defaultUser")
    public User getUserById(Long id) {
        return restTemplate.getForObject("http://USER-SERVICE/users/{1}", User.class, id);
    }

    public User defaultUser() {
        return new User();
    }
}

(2)我们也可以像下面这样实现一个级联的降级策略:
注意:级联的降级策略,最终的降级逻辑一定不能是一个依赖网络请求的处理,而是一个能够稳定地返回结果的处理逻辑。
public class UserService {
    @Autowired
    RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "defaultUser")
    public User getUserById(Long id) {
        return restTemplate.getForObject("http://USER-SERVICE/users/{1}", User.class, id);
    }

    @HystrixCommand(fallbackMethod = "defaultUserSec")
    public User defaultUser(Long id) {
        return restTemplate.getForObject("http://USER-SERVICE-BACK/users/{1}", User.class, id);
    }

    public User defaultUserSec() {
        return new User();
    }
}
评论0