springCloud三:断路器Hystrix

Hystrix的原理跟Demo可以看这篇博文http://blog.didispace.com/springcloud3/

Hystrix 能使你的系统在出现依赖服务失效的时候,通过隔离系统所依赖的服务,防止服务级联失败,同时提供失败回退机制

更优雅地应对失效,并使你的系统能更快地从异常中恢复。

Hystrix能做什么?

  • 在通过第三方客户端访问(通常是通过网络)依赖服务出现高延迟或者失败时,为系统提供保护和控制
  • 在分布式系统中防止级联失败
  • 快速失败(Fail fast)同时能快速恢复
  • 提供失败回退(Fallback)和优雅的服务降级机制
  • 提供近实时的监控、报警和运维控制手段

Hystrix设计原则?

  • 防止单个依赖耗尽容器(例如 Tomcat)内所有用户线程
  • 降低系统负载,对无法及时处理的请求快速失败(fail fast)而不是排队
  • 提供失败回退,以在必要时让失效对用户透明化
  • 使用隔离机制(例如『舱壁』/『泳道』模式,熔断器模式等)降低依赖服务对整个系统的影响
  • 针对系统服务的度量、监控和报警,提供优化以满足近实时性的要求
  • 在 Hystrix 绝大部分需要动态调整配置并快速部署到所有应用方面,提供优化以满足快速恢复的要求
  • 能保护应用不受依赖服务的整个执行过程中失败的影响,而不仅仅是网络请求

Hystrix实现原理-命令模式

  • 将所有请求外部系统(或者叫依赖服务)的逻辑封装到 HystrixCommand或者HystrixObservableCommand(依赖RxJava)对象中
  • Run()方法为要实现的业务逻辑,这些逻辑将会在独立的线程中被执行当请求依赖服务时出现拒绝服务、超时或者短路(多个依赖服务顺序请求,
  • 前面的依赖服务请求失败,则后面的请求不会发出)时,执行该依赖服务的失败回退逻辑(Fallback) 

springCloud三:断路器Hystrix_第1张图片

如果某程序或class要使用Hystrix,只需简单继承 HystrixCommand/HystrixObservableCommand并重写run()/construct()
然后调用程序实例化此class并执行execute()/queue()/observe()/toObservable


public class HelloWorldHystrixCommand extends HystrixCommand{
    private final String name;
    public HelloWorldHystrixCommand(String name) {
        super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
        this.name = name;
    }
 
    @Override
    protected String run() throws Exception {
        //Thread.sleep(100);
        return "hello"+name;
    }

public static void main(String[] args){
    String result = new HelloWorldHystrixCommand("test").execute();
    System.out.println(result);//控制台显示是hellotest
}
}

Hystrix实现原理-舱壁模式

  • 货船为了进行防止漏水和火灾的扩散,会将货仓分隔为多个,当发生灾害时,将所在货仓进行隔离就可以降低整艘船的风险。

springCloud三:断路器Hystrix_第2张图片

Hystrix实现原理-隔离策略

  • 应用在复杂的分布式结构中,可能会依赖许多其他的服务,并且这些服务都不可避免地有失效的可能。如果一个应用没有与依赖服务的失效隔离开
  • 来,那么它将有可能因为依赖服务的失效而失效。
  • Hystrix将货仓模式运用到了服务调用者上。为每一个依赖服务维护一个线程池(或者信号量),当线程池占满,该依赖服务将会立即拒绝服务而
  • 不是排队等待。
  • 每个依赖服务都被隔离开来,Hystrix 会严格控制其对资源的占用,并在任何失效发生时,执行失败回退逻辑。 

springCloud三:断路器Hystrix_第3张图片

上图的左边2个是线程池资源隔离示意图,右边的1个是信号量资源隔离示意图,我们先来看左边的示意图。

当用户请求服务A和服务I的时候,tomcat的线程(图中蓝色箭头标注)会将请求的任务交给服务A和服务I的内部线程池里面的线程

(图中橘色箭头标注)来执行,tomcat的线程就可以去干别的事情去了,当服务A和服务I自己线程池里面的线程执行完任务之后,

就会将调用的结果返回给tomcat的线程,从而实现资源的隔离,当有大量并发的时候,服务内部的线程池的数量就决定了整个服务

的并发度,例如服务A的线程池大小为10个,当同时有12请求时,只会允许10个任务在执行,其他的任务被放在线程池队列中,

或者是直接走降级服务,此时,如果服务A挂了,就不会造成大量的tomcat线程被服务A拖死,服务I依然能够提供服务。

整个系统不会受太大的影响。

2、信号量

信号量的资源隔离只是起到一个开关的作用,例如,服务X的信号量大小为10,那么同时只允许10个tomcat的线程(此处是tomcat

的线程,而不是服务X的独立线程池里面的线程)来访问服务X,其他的请求就会被拒绝,从而达到限流保护的作用。

当请求的服务网络开销比较大的时候,或者是请求比较耗时的时候,我们最好是使用线程隔离策略,这样的话,可以保证大量的容器(tomcat)线程

可用,不会由于服务原因,一直处于阻塞或等待状态,快速失败返回。而当我们请求缓存这些服务的时候,我们可以使用信号量隔离策略,因为这类

服务的返回通常会非常的快,不会占用容器线程太长时间,而且也减少了线程切换的一些开销,提高了缓存服务的效率。

Hystrix实现原理-观察者模式

  • Hystrix通过观察者模式对服务进行状态监听。
  • 每个任务都包含有一个对应的Metrics,所有Metrics都由一个ConcurrentHashMap来进行维护,Key是CommandKey.name() 


你可能感兴趣的:(springCloud)