天天看点

Netflix Hystrix

发博词

此博文内容全部来自网上资料及消化后的补充。

基础知识

如何缓解服务器雪崩

一般情况对于服务依赖的保护主要有3中解决方案,熔断模式和隔离模式都属于出错后的容错处理机制,而限流模式则可以称为预防模式:

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

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

(3)限流模式:限流模式主要是提前对各个类型的请求设置最高的QPS阈值,若高于设置的阈值则对该请求直接返回,不再调用后续资源。这种模式不能解决服务依赖的问题,只能解决系统整体资源分配问题,因为没有被限流的请求依然有可能造成雪崩效应。

熔断设计

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

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

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

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

Hystrix的熔断器有三种类型的状态:open、half-open以及closed:

Netflix Hystrix

##隔离设计- 线程隔离和信号量隔离

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

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

(1):线程隔离

把执行依赖代码的线程与请求线程(如:jetty线程)分离,请求线程可以自由控制离开的时间(异步过程)。

通过线程池大小可以控制并发量,当线程池饱和时可以提前拒绝服务,防止依赖问题扩散。

线上建议线程池不要设置过大,否则大量堵塞线程有可能会拖慢服务器。

(2):线程隔离的优缺点

线程隔离的优点:

[1]:使用线程可以完全隔离第三方代码,请求线程可以快速放回。

[2]:当一个失败的依赖再次变成可用时,线程池将清理,并立即恢复可用,而不是一个长时间的恢复。

[3]:可以完全模拟异步调用,方便异步编程。

线程隔离的缺点:

[1]:线程池的主要缺点是它增加了cpu,因为每个命令的执行涉及到排队(默认使用SynchronousQueue避免排队),调度和上下文切换。

[2]:对使用ThreadLocal等依赖线程状态的代码增加复杂性,需要手动传递和清理线程状态。

NOTE: Netflix公司内部认为线程隔离开销足够小,不会造成重大的成本或性能的影响。

Netflix 内部API 每天100亿的HystrixCommand依赖请求使用线程隔,每个应用大约40多个线程池,每个线程池大约5-20个线程。

(3):信号隔离

信号隔离也可以用于限制并发访问,防止阻塞扩散, 与线程隔离最大不同在于执行依赖代码的线程依然是请求线程(该线程需要通过信号申请),

如果客户端是可信的且可以快速返回,可以使用信号隔离替换线程隔离,降低开销.

信号量的大小可以动态调整, 线程池大小不可以.

超时机制设计

超时分两种,一种是请求的等待超时,一种是请求运行超时。

等待超时:在任务入队列时设置任务入队列时间,并判断队头的任务入队列时间是否大于超时时间,超过则丢弃任务。

运行超时:直接可使用线程池提供的get方法

参考:

​​​服务隔离神器-Hystrix​​​​Hystrix线程隔离技术解析-线程池​​​​Hystrix线程隔离技术解析-信号量​​微服务熔断与隔离

Hystrix请求缓存和COLLAPSER

在Hystrix中有个Request的概念,有一些操作需要在request中进行。Collapser可以合并多个请求一起调用,Collapser可以用来一起调用一批请求,在第一个调用get时会对积压的command一起调用。

参考:

​ Hystrx权威指南–Hystrix请求缓存和COLLAPSER​​

Hystrix执行流程

Netflix Hystrix

降级逻辑。以下四种情况将触发getFallback调用:

  1. 熔断器开启拦截调用
  2. 线程池/队列/信号量是否跑满
  3. run()方法抛出非HystrixBadRequestException异常。
  4. run()方法调用超时

    没有实现getFallback的Command将直接抛出异常,fallback降级逻辑调用成功直接返回,降级逻辑调用失败抛出异常.

​​Hystrx权威指南–Hystrix执行流程​​

Hystrix DashBoard

  1. 圆圈的颜色和大小分别代表健康和访问量
  2. 折线图表示两分钟内的请求速率,用来展示访问量的相对变化
  3. Hosts:集群中报告信息的节点个数
  4. Median
  5. Mean
  6. 90th、99th和99.5th分别代表90%的访问量的延迟时间、99%的访问量的延迟时间和99.5%的访问量的延迟时间
  7. 6种颜色的数字,新版的有7种,绿色代表访问成功,深蓝色代表短路,浅蓝色代表Bad Request,橘黄色代表请求线程超时,紫色代表线程池Rejects,红色代表失败,灰色代表失败的百分比,事实上,Hystrix对一次请求的状态标识多达18种,详情请看HystrixEventType;
  8. Circuit的状态 Open、Closed
  9. Host:54.0/s 请求速率

参考

继续阅读