Hystrix是什么

来源:互联网 发布:java 验证身份证号 编辑:程序博客网 时间:2024/06/03 14:35

Hystrix是什么?

官方地址:https://github.com/Netflix/Hystrix

Hystrix是由Netflix开源的一个服务隔离组件,通过服务隔离来避免由于依赖延迟、异常,引起资源耗尽导致系统不可用的解决方案。

在分布式系统,我们一定会依赖各种服务,那么这些个服务一定会出现失败的情况,Hystrix就是这样的一个工具,它通过提供了逻辑上延时和错误容忍的解决力来协助我们完成分布式系统的交互。Hystrix 通过分离服务的调用点,阻止错误在各个系统的传播,并且提供了错误回调机制,这一系列的措施提高了系统的整体服务弹性。

Hystrix 的历史

Hystrix 是2011 从Netflix API 团队发展而来。 2012 Hystrix持续发展并且成熟,并且有非常多的团队开始采用Hystrix.现在在Netflix每天有数十万的线程,数百万的独立信号量通过Hystrix执行,这几大增强了服务的弹性和服务时间。

Hystrix 是干嘛的

Hystrix 被设计用来做了下面几件事:

  • 保护系统间的调用延时以及错误,特别是通过第三方的工具的网络调用
  • 阻止错误在分布式系统之前的传播
  • 快速失败和迅速恢复
  • 错误回退和优雅的服务降级

Hystrix 解决了什么问题

应用在复杂的分布式系统中存在非常多的依赖,这其中一些服务不可避免的会失败,如果主应用程序没有和依赖的服务隔离开来,那么它的服务成功率就会下降

举个例子, 一个服务依赖30个不同的服务,每个服务的服务成功率为99.99%,这个服务的成功率就可以这样计算:
99.99*99.99。。。。。30 = 99.7 这样算来 1000个请求中就有3个是失败的, 这样一来 每个月基本上会有差不多2个小时的停机时间
这只是一个计算值,现实情况可以比这个更糟糕。

尽管我们我们可以将每个服务的成功率再往上提升,比如现在没1万个请求才会失败一个,但是还是任然每个月了数小时的停机,

这里写图片描述

这里写图片描述

这里写图片描述

在应用程序中,每一个通过网络或者使用第三方客户端发送出去的请求都有可能会失败,比失败更糟糕的是,这会增加服务间的调用延时。

上面的这些问题会变得更加的严重,当我们通过第三方客户端发送网络请求,因为第三方客户端对于我们而言是“黑盒”,并且它的实现是随时可能改变的。并且每一个客户端的资源配置都是不同的,这样就非常的难监控和改变。
……
网络连接失败或者降级,服务或者服务机器停机或者变慢,新的客户端或者部署的新的服务改变了原有的行为,亦或者客户端有bugs。

上面的所有错误形式都需要被单独隔离出来,这样不至于一个简单的错误导致整个系统的失败。

Hystrix 的设计原则是什么

Hystrix工作方式如下:

  • 阻止一个单独的依赖耗尽系统的所有线程,比如(tomcat)
  • 使用快速失败代替将这个请求排队
  • 在任何可能失败的地方提供后退机制来确保用户不会看到错误

  • 使用隔离技术(比如:隔板,泳道,环路切断 模式)降低一个依赖的失败对整个系统的影响

  • 优化使得系统可以近乎实时的收集,监控,报警

  • 优化使得系统可以近乎实时的修改,并且可以近乎实时生效

  • 保护系统不仅仅在网络层面,也包括客户端层面的依赖执行的失败

Hystrix 是怎样的实现这些目标

Hystrix 通过如下的方式实现了这些目标:

  • 通过使用命令模式包装所有的调用外部系统的请求,这些个请求都单独的运行在不同的线程中,在Hystrix中主要通过 “HystirxCommand”,”HystixObservableCommand”实现

  • 调用超时比我们自定义的超时时间更久,所以我们在使用的过程中最好自定义网络调用的超时时间,在Hystrix中,提供了配置可以修改默认的超时时间,那么超时间到底应该定义为多少? 就一般经验值而言,设置为服务成功率为99.5%时的平均时间

  • 每一个服务都维护着一个小的线程池或者信号量,一旦线程池或者信号量饱和了,那么采取的策略是拒绝请求而不是将请求排队

  • 记录成功,失败,超时,线程拒绝数据
  • 提供一个回调接口,当一个请求失败,或者被拒绝,超时亦或者因为短路而拒绝

  • 监控系统运行数据并且可以近乎实时的修改系统配置

  • 一段时间内当短路发生时,拒绝所有的请求,或者当错误率超过了阀值

当你使用Hystrix包装所有的依赖时,系统的整体架构和上面的那张图差不多一致的,每一个依赖之间都是相互隔离的,这样可以为每一服务提供失败回滚逻辑等等。

这里写图片描述


主要有3种解决方案:

  • (1) 熔断模式:

    这种模式主要是参考电路熔断,如果一条线路电压过高,保险丝会熔断,防止火灾。放到我们的系统中,如果某个目标服务调用慢或者有大量超时,此时,熔断该服务的调用,对于后续调用请求,不在继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用。

  • (2) 隔离模式:

    这种模式就像对系统请求按类型划分成一个个小岛的一样,当某个小岛被火烧光了,不会影响到其他的小岛。例如可以对不同类型的请求使用线程池来资源隔离,每种类型的请求互不影响,如果一种类型的请求线程资源耗尽,则对后续的该类型请求直接返回,不再调用后续资源。这种模式使用场景非常多,例如将一个服务拆开,对于重要的服务使用单独服务器来部署,再或者公司最近推广的多中心。

  • (3)限流模式:

    上述的熔断模式和隔离模式都属于出错后的容错处理机制,而限流模式则可以称为预防模式。限流模式主要是提前对各个类型的请求设置最高的QPS阈值,若高于设置的阈值则对该请求直接返回,不再调用后续资源。这种模式不能解决服务依赖的问题,只能解决系统整体资源分配问题,因为没有被限流的请求依然有可能造成雪崩效应。

熔断设计

在熔断的设计主要参考了hystrix的做法。其中最重要的是三个模块:熔断请求判断算法、熔断恢复机制、熔断报警

  • (1)熔断请求判断机制算法:
    使用无锁循环队列计数,每个熔断器默认维护10个bucket,每1秒一个bucket,每个blucket记录请求的成功、失败、超时、拒绝的状态,默认错误超过50%且10秒内超过20个请求进行中断拦截。

  • (2)熔断恢复:
    对于被熔断的请求,每隔5s允许部分请求通过,若请求都是健康的(RT<250ms)则对请求健康恢复。

  • (3)熔断报警:
    对于熔断的请求打日志,异常请求超过某些设定则报警

隔离设计

隔离的方式一般使用两种:
(1)线程池隔离模式:使用一个线程池来存储当前的请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求堆积入线程池队列。这种方式需要为每个依赖的服务申请线程池,有一定的资源消耗,好处是可以应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理)。

(2)信号量隔离模式:使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃改类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)。

原创粉丝点击