一般是指软件系统中,由于某些原因使得服务出现了过载现象,为防止造成整个系统故障,从而采用的一种保护措施,所以很多地方把熔断亦称为过载保护。很多时候刚开始可能只是系统出现了局部的、小规模的故障,然而由于种种原因,故障影响的范围越来越大,最终导致了全局性的后果。
适用场景:防止应用程序直接调用那些很可能会调用失败的远程服务或共享资源
当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务和页面有策略的降级,以此释放服务器资源以保证核心任务的正常运行。
一种因 服务提供者 的不可用导致 服务调用者 的不可用,并将不可用 逐渐放大 的过程
分布式系统中经常会出现某个基础服务不可用造成整个系统不可用的情况, 这种现象被称为服务雪崩效应.。如:在分布式系统架构中多个系统之间通常是通过远程RPC调用进行通信,也就是 A 系统调用 B 系统服务,B 系统调用 C 系统的服务。当尾部应用 C 发生故障而系统 B 没有服务降级时候可能会导致 B,甚至系统 A 瘫痪。
为了应对服务雪崩, 一种常见的做法是手动服务降级. 而Hystrix的出现,给我们提供了另一种选择.
a)硬件故障:硬件损坏造成的服务器主机宕机, 网络硬件故障造成的服务提供者的不可访问
b)程序Bug
c)缓存击穿:一般发生在缓存应用重启,所有缓存被清空时,以及短时间内大量缓存失效时,大量的缓存不命中,使请求直击后端,造成服务提供者超负荷运行,引起服务不可用
d)用户大量请求:在秒杀和大促开始前,如果准备不充分,用户发起大量请求也会造成服务提供者的不可用
a)用户重试:在服务提供者不可用后, 用户由于忍受不了界面上长时间的等待,而不断刷新页面甚至提交表单
b)代码逻辑重试: 服务调用端的会存在大量服务异常后的重试逻辑
a)同步等待造成的资源耗尽:当服务调用者使用 同步调用 时, 会产生大量的等待线程占用系统资源. 一旦线程资源被耗尽,服务调用者提供的服务也将处于不可用状态, 于是服务雪崩效应产生了。
流量控制
a)网关限流:因为Nginx的高性能, 目前一线互联网公司大量采用Nginx+Lua的网关进行流量控制, 由此而来的OpenResty也越来越热门
b)用户交互限流:具体措施有: 1. 采用加载动画,提高用户的忍耐等待时间. 2. 提交按钮添加强制等待时间机制.
c)关闭重试
改进缓存模式
a)缓存预加载
b)同步改为异步刷新
服务自动扩容
a)AWS的auto scaling
服务调用者降级服务
a)资源隔离:主要是对调用服务的线程池进行隔离
b)对依赖服务进行分类:根据具体业务,将依赖服务分为: 强依赖和若依赖。强依赖服务不可用会导致当前业务中止,而弱依赖服务不可用不会导致当前业务中止
c)不可用服务的调用快速失败:一般通过 超时机制, 熔断器 和熔断后的 降级方法 来实现
Netflix的 Hystrix 是一个帮助解决分布式系统交互时超时处理和容错的类库,它拥有保护系统的能力.
Hystrix的设计原则包括:
资源隔离
货船为了防止漏水和火灾的扩散,将货仓分隔为多个,这种资源隔离减少风险的方式被称为Bulkheads(舱壁隔离模式)。Hystrix将同样的模式运用到了服务调用者上。
在一个高度服务化的系统中,我们实现的一个业务逻辑通常会依赖多个服务,比如: 商品详情展示服务会依赖商品服务、 价格服务、商品评论服务。调用三个依赖服务会共享商品详情服务的线程池, 如果其中的商品评论服务不可用, 就会出现线程池里所有线程都因等待响应而被阻塞,从而造成服务雪崩。 如图所示:
Hystrix通过将每个依赖服务分配独立的线程池进行资源隔离,用户的请求将不再直接访问服务,而是通过线程池中的空闲线程来访问服务,如果线程池已满,则会进行降级处理,用户的请求不会被阻塞,至少可以看到一个执行结果(例如返回友好的提示信息),而不是无休止的等待或者看到系统崩溃。如下图所示, 当商品评论服务不可用时, 即使商品服务独立分配的20个线程全部处于同步等待状态,也不会影响其他依赖服务的调用.
信号隔离也可以用于限制并发访问,防止阻塞扩散,与线程隔离最大不同在于执行依赖代码的线程依然是请求线程(该线程需要通过信号申请,如果客户端是可信的且可以快速返回,可以使用信号隔离替换线程隔离,降低开销。信号量的大小可以动态调整,线程池大小不可以。
熔断器是位于线程池之前的组件。用户请求某一服务之后,Hystrix会先经过熔断器,此时如果熔断器的状态是打开,这时将直接进行降级处理,不会继续将请求发到线程池。熔断器相当于在线程池之前的一层屏障。每个熔断器默认维护10个bucket ,每秒创建一个bucket ,每个blucket记录成功,失败,超时,拒绝的次数。当有新的bucket被创建时,最旧的bucket会被抛弃。
熔断器模式定义了熔断器开关相互转换的逻辑:
三种状态:
服务的健康状况 = 请求失败数 / 请求总数.
熔断器开关由关闭到打开的状态转换是通过当前服务健康状况和设定阈值比较决定的。
熔断器的开关能保证服务调用者在调用异常服务时,快速返回结果,避免大量的同步等待,并且熔断器能在一段时间后继续侦测请求执行结果,提供恢复服务调用的可能。
Hystrix提供的熔断器具有自我反馈,自我恢复的功能,Hystrix会根据调用接口的情况,让熔断器在closed、open、half-open三种状态之间自动切换:
Hystrix使用命令模式(继承HystrixCommand类)来包裹具体的服务调用逻辑(run方法),并在命令模式中添加了服务调用失败后的降级逻辑(getFallback).
同时我们在Command的构造方法中可以定义当前服务线程池和熔断器的相关参数, 如下代码所示:
整理自:https://segmentfault.com/a/1190000005988895、https://blog.csdn.net/smillest/article/details/80660565
原文:https://www.cnblogs.com/whatarewords/p/10985263.html