高可用服务容错框架Hystrix

来源:互联网 发布:nginx 访问日志 编辑:程序博客网 时间:2024/06/05 02:33

Hystrix具体要实现的目标以及是用什么方法去实现的!

Hystrix要解决的问题?

在复杂的分布式系统架构中,每个服务都有很多的依赖服务,而每个依赖服务都可能会故障,如果服务没有和自己的依赖服务进行隔离,那么可能某一个依赖服务的故障就会拖垮当前这个服务。Hystrix就是通过相应方法来阻止当前服务被拖垮的一个容错框架!

具体见下图Hystrix 项目Wiki中给出的图片:下面三张图分别对应通常服务调用中从最开始的正常调用,到出现一个调用异常(调用方没有获取依赖服务I的响应,当前进程卡住便启动其他进程来重新调用该服务)最后所有的进程资源全部用来访问该服务而导致资源耗尽从而使当前服务崩溃,最后可能引起整个分布式系统的雪崩!


Hystrix的具体设计原则:

(1)阻止任何一个依赖服务耗尽所有的资源,比如tomcat中的所有线程资源

(2)避免请求排队和积压,采用限流和fail fast来控制故障

(3)提供fallback降级机制来应对故障

(4)使用资源隔离技术,比如bulkhead(舱壁隔离技术),swimlane(泳道技术),circuit breaker(短路技术),来限制任何一个依赖服务的故障的影响

(5)通过近实时的统计/监控/报警功能,来提高故障发现的速度

(6)通过近实时的属性和配置热修改功能,来提高故障处理和恢复的速度

(7)保护依赖服务调用的所有故障情况,而不仅仅只是网络故障情况


Hystrix的实现方法:

(1)通过HystrixCommand或者HystrixObservableCommand来封装对外部依赖的访问请求,这个访问请求一般会运行在独立的线程中,资源隔离。

         Hystrix会把所有的访问服务的行为封装在HystrixCommand或者HystrixObservableCommand中,为什么会有这两种Command,这里我解释一下,HystrixCommand的设计是用来封装请求行为中只有一条返回结果。而HystrixObservableCommand可以封装请求行为为多条的响应。 针对开头我说的在一般分布式系统中的服务之间的依赖行为可能会出现的雪崩行为,Hystrix的解决办法是将要访问的资源进行隔离,这是什么意思呢,就是Hystrix通过严格控制访问某个资源的线程数量,来解决服务中资源可能会被耗尽的危机!而Hystrix中的资源隔离有两种隔离策略,一个是通过线程(Thread)一个是通过信号量(Semaphore),这两种资源隔离策略有什么区别呢?这里简单介绍一下,通过Thread进行资源隔离的话,所有访问同一个服务的请求会被放到一个CommandGroup中,每一个请求Hystrix会为其生成一个command,具有相同commandKey的请求会进入到一个commandGroup中,然后在commandGroup中会生成不定数目的线程池,这里的线程池我说一下,每个线程池会有一个ThreadPollKey,再生成command时,我们可以在command的构造方法中指定想要每个command属于那个线程池。例如下面的代码就是具体定义一个command ,其中的构造函数中就定义了封装run方法中的请求的这个command的具体设置。凡是所有访问http://localhost:8015/bad这个接口的所有command线程都会进入名字叫做bad这个线程池中来访问具体的资源。若果没有设置ThreadPollKey的话,CommandGroup中只有一个线程池,默认取值是CommandGroupKey,所以Hystrix默认的隔离粒度也是整个服务,而不是某个具体的接口。



(2)对于超出我们设定阈值的服务调用,直接进行超时,不允许其耗费过长时间阻塞住。这个超时时间默认是99.5%的访问时间,但是一般我们可以自己设置一下

(3)为每一个依赖服务维护一个独立的线程池,或者是semaphore,当线程池已满时,直接拒绝对这个服务的调用

(4)对依赖服务的调用的成功次数,失败次数,拒绝次数,超时次数,进行统计

           这里的统计单位就是我上面所说的进行资源隔离时的线程池,所有在一个线程池中的command会保存各自调用结果信息以供监控时使用。

(5)如果对一个依赖服务的调用失败次数超过了一定的阈值,自动进行熔断,在一定时间内对该服务的调用直接降级,一段时间后再自动尝试恢复

          这里的服务熔断的内容我来讲一下,Hystrix中的熔断设计思想来源于我们的日常生活电路断路器,如果家里的某条电路的电压过大而导致产生较强电流线路承受不住的话,电路断路器会切断家里的电路,以保护其他电路不搜损坏!在我们分布式系统中同样的道理,当调用某个服务时由于服务提供者的原因 导致我们调用这个服务总是失败,失败的原因可能有很多,比如请求超时,接口损坏,网络延时等等。在一定时间内(Hystrix默认是10秒20次)请求错误数达到一定阈值的时候,就会触发熔断器打开(CircutBreaker),当熔断器打开时,Hystrix会禁止所有的请求再来访问该损坏的服务。不过熔断器在过一段时间后(默认时5秒)会处于一个半开的状态,此时Hystrix允许访问服务一次,若访问成功,则把熔断器关闭,否则就打开。具体的配置参数以及配置参数都是什么含义,下面有一个连接,里面讲的很清楚。参数的配置位置,我们可以根据自己的需求使用不同的方法配置,这里我讲三种配置方法,第一种也是全局的配置,是针对所有服务而言的,就是在我们的整合Hystrix项目中的application.properties配置文件中来配置,这种方法也是最简单的,不过不能针对一些特定的服务来做限定,第二种方法就是在具体的command类中构造方法中定义,相关配置案例,见Hystrix项目中的WIKI中有部分案例。第三种方法就是使用注解的方式,通过@HystrixCommand注解来针对特定的接口配置Hystrix属性。后边两种方法,由于都是针对特定的方法或者请求来做限定的,所以可以针对特定的服务进行配置。关于在调研中先要认为指定熔断的粒度,经过测试,Hystrix的熔断里度是根据在进行资源隔离的时候产生的线程池为单位的,如果我在整合Hystrix时没有为特定的command制定对应的线程池的话,则相应的以serviceId为commandGroup中只含有一个以commandGroupKey为名的线程池。则熔断的粒度就是整个服务了。具体要做api接口熔断的话,需要为每个command制定一个特定的ThreadPoolKey,那样的话熔断发生时,熔断的只是针对给接口的所有请求,而不是整个服务了。

(6)当一个服务调用出现失败,被拒绝,超时,短路等异常情况时,自动调用fallback降级机制

      这里的fallback降之的是当熔断器打开时,所有再来的服务将不能在访问相应的服务,Hystrix会直接将请求降级处理,通过定义相应的降级方法,来响应具体的请求。这里我目前知道两种fallback的配置方法,一个是在zuul网关中整合了Hystrix时进行的回退设置(或者直接说是针对zuul的回退方法设置,因为zuul是默认整合了Hystrix的),在zuul中可以定义一个具体的zuulfallback类来实现fallback,具体的案例可见我在网关中熟实现的回退。另一种方法实在具体的command中配置,可以通过@HystrixCommand注解中的fallbackMethod属性制定具体的回退方法,那么针对gaicommand的请求如果失败时,则会调用配置的回退方法。

(7)对属性和配置的修改提供近实时的支持

       Hystrix内部好像使用archaius框架实现的属性配置的动态管理,好像每一分钟会自动读取一次配置文件,所以我们可以直接在配置文件中配置相应的属性,Hystrix都能读取到我们的配置。这里具体是怎么实现的我目前还不是很清楚。


1、下面数WIKI中的Hystrix工作流程图:

Hystrix参数说明:http://m635674608.iteye.com/blog/2324865,可通过具体公司要求设置Hystrix相应的属性值,Hystrix使用archaius来实现属性配置的动态管理,archaius会默认读取classpath下的config. properties文件中的属性,所以现在我调研的配置hystrix的属性实在项目的application.properties中配置,这种事针对全局的服务而用的配置!针对某个特定服务的hystrix配置,目前zuul网关中我还没有找到配置方法,如果是针对单个服务调用者整合的hystrix的话,可以在具体的调用方法上使用@HystrixCommand注释中配置相应的属性例如:

@HystrixCommand(commandProperties={

@HystrixProperties(name="属性名",value="属性值")

@HystrixProperties(name="属性名",value="属性值")

}

public User findById(Long id){

.........

}

HystrixDashboard

Hystrix在工作过程中,我们可以通过HystrixDashboard来来可视化的监控与统计所有服务实例的访问情况。启用HystrixDashboard时,我们可以选择新建一个Dashboard的项目,或者在服务网关上直接整合HystrixDashboard,具体整合方法如下:

在项目pom文件中加入dashbord的依赖

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-boot-starter.hystrix-dashboard</artifactId></dependency>

然后在项目启动类上加上@EnableHystrixDashboard使面板可用!然后我们便可以通过http://IP:PORT/hystrix访问监控配置页面如下:

然后在地址框中输入整合hystrix项目的的根路径访问地址加上hystrix.stream端点来设置需要监控的hystrix流,然后随便输入一个Title点击Monitor Stream按钮便可以启动监控:


原创粉丝点击