Spring Cloud Hystrix 服务容错保护

2019-10-15 0 By admin

Hystrix是国外知名的视频网站Netflix所开源的非常流行的高可用架构框架。Hystrix能够完美的解决分布式系统架构中打造高可用服务面临的一系列技术难题。
Hystrix “豪猪”,具有自我保护的能力。hystrix 通过如下机制来解决雪崩效应问题。

一、Hystrix 特征

1、资源隔离:包括线程池隔离和信号量隔离,限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其他服务调用。
2、降级机制:超时降级、资源不足时(线程或信号量)降级,降级后可以配合降级接口返回托底数据。
3、融断:当失败率达到阀值自动触发降级(如因网络故障/超时造成的失败率高),熔断器触发的快速失败会进行快速恢复。
4、缓存:提供了请求缓存、请求合并实现。

二、构建 Hystrix 命令

首先构建一个HystrixCommand或者是HystrixObservableCommand对象,用来表示对依赖服务的操作请求,同时传递所有需要的参数。这两个command对象分别针对不同的应用场景。
1、HystrixCommand:用在依赖的服务返回单个操作结果的时候。
2、HystrixObservableCommand:用在依赖的服务返回多个操作结果的时候。

三、命令模式中包含四个对象

1、Receiver:接受者,处理业务逻辑,
2、Command:抽象命令,就是简简单单的接口,比如你要实现什么样的命令。
3、ConcreteCommand:具体的命令实现类,在类中有一个属性是接受者。
4、Invoker:调用者,这个类中有一个属性是command接口。

package com.bobo;
/**
 * @author wuxiaobo@didachuxing.com
 * @create 2018-10-24 20:39
 **/
public class Test {
}
class Receiver {
    public void execute () {
        System.out.println("Hello World");
    }
}
interface Command {
    public void sayHello();
}
class ConcreteCommand implements Command {
    private Receiver receiver;
    public ConcreteCommand (Receiver receiver) {
        this.receiver = receiver;
    }
    @Override
    public void sayHello() {
        receiver.execute();
    }
}
class Invoker {
    private Command command;
    public Invoker(Command command) {
        this.command = command;
    }
    public void  sayHello () {
        command.sayHello();
    }
}

上面的这个例子就是最简单的命令模式,提到的那两个类就是对command的进一步封装了。

四、命令执行

Hystrix 一共存在4种命令的执行方式,而Hystrix在执行时会根据创建的Command对象以及具体的情况来选择一个执行。
其中HystrixCommand实现了下面两个执行方式。
1、execute ():同步执行,从依赖的服务返回一个单一的结果对象,或是在发生错误的时候抛出异常。
2、queue ():异步执行,直接返回一个Future对象,其中包含了服务执行结束时要返回的单一结果对象。
而HystrixObservableCommand实现了另外两种执行方式。
1、observe ():返回Observable对象,它代表了操作的多个结果,它是一个HotObservable.
2、toObservable ():同样会返回Observable对象,也代表了操作的多个结果,但它返回的是一个Cold Observable。

五、Rxjava 介绍

在Hystrix的底层实现中大量使用了RxJava,这里来介绍一下Rxjava
Observable用来向订阅者Subscriber对象发布事件, Subscriber对象则在接收到事件后对其进行处理,而在这里所指的事件通常就是对依赖服务的调用。
一个observable可以发出多个事件,直到结束或是发生异常。Observable对象每发出一个事件,就会调用对应观察者Subscriber对象的onNext ()方法。每一个Observable的执行,最后一定会通过调用Subscriber. onCompleted ()或者Subscriber.onError()来结束该事件的操作流。

在这里我们对于事件源observable提到了两个不同的概念: Hot Observable和ColdObservable,分别对应了上面command. observe ()和command.toObservable ()的返回对象。
其中Hot Observable,它不论“事件源”是否有“订阅者”,都会在创建后对事件进行发布,所以对于Hot Observable的每一个“订阅者”都有可能是从“事件源”的中途开始的,并可能只是看到了整个操作的局部过程。
而Cold Observable在没有 “订阅者”的时候并不会发布事件,而是进行等待,直到有“订阅者”之后才发布事件,所以对于ColdObservable的订阅者,它可以保证从一开始看到整个操作的全部过程。

六、结果是否被缓存

若当前命令的请求缓存功能是被启用的 ,如果该命令缓存命中,那么缓存的结果就会立即以Observable对象的形式返回。

七、断路器是否被打开

在命令结果没有缓存命中的时候,Hystrix在执行命令前需要检查断路器是否是打开状态:
1、如果断路器是打开的,那么Hystrix不会执行命令,然后是转接到fallback处理逻辑。
2、如果断路器是关闭的,那么Hystrix跳转到 第五步,检查是否有可用资源来执行命令。