1、熔断器模式
服务的健康状况=请求失败数/请求总数
熔断器开关由关闭到打开的状态转换是通过当前服务健康状况和设定的阈值比较决定的
1)当熔断器开关关闭时,请求被允许通过熔断器。如果当前健康状况高于设定阈值,开关继续保持关闭。如果当前健康状况低于设定阈值,开关则切换为打开状态
2)当熔断器开关打开时,请求被禁止通过
3)当熔断器开关处于打开状态,经过一段时间后,熔断器会自动进入半开状态,这时熔断器只允许一个请求通过。当该请求调用成功时,熔断器恢复到关闭状态。若该请求失败,熔断器继续保持打开状态,接下来的请求被禁止通过
熔断器的开关能保证服务调用者在调用异常服务时,快速返回结果,避免大量的同步等待。并且熔断器能在一段时间后继续侦测请求执行结果,提供恢复服务调用的可能
2、Hystrix工作原理
1)每次调用都会创建一个HystrixCommand
2)执行execute或queue做同步或异步调用
3)判断熔断器是否打开,如果打开跳到步骤8,否则进入步骤4
4)判断线程池/信号量是否跑满,如果跑满进入步骤8,否则进入步骤5
5)调用HystrixCommand的run方法,如果调用超时进入步骤8
6)判断是否调用成功,返回成功调用结果,如果失败进入步骤8
7)计算熔断器状态,所有的运行状态上报给熔断器,用于统计从而判断熔断器状态
8)如果有降级方法走降级处理逻辑,没有则抛出异常。根据上方的步骤可以得出以下四种情况会进入降级处理:熔断器打开、线程池/信号量跑满、调用超时、调用失败
9)返回执行成功结果
3、Hystrix线程和信号量隔离
线程池隔离:线程隔离会为每一个依赖的服务单独的创建一个线程池进行隔离,每次调用服务都发生在它对应的线程池里,通过线程池里的线程调用后台的服务
信号量隔离:当并发请求数达到阈值时,请求线程可以快速失败,执行降级
信号量隔离 | 线程池隔离 | |
---|---|---|
优点 | 轻量,无额外开销 | 支持排队和超时;支持异步调用 |
缺点 | 不支持任务排队和主动超时;不支持异步调用 | 线程调用会产生额外的开销 |
适用场景 | 受信客户;高扇出(网关);高频高速调用(缓存) | 不受信客户;有限扇出 |
4、Hystrix核心配置
Hystrix的属性存在下面4个不同优先级别的配置(优先级由低到高)
- 全局默认值:如果没有设置下面三个级别的属性,那么这个属性就是默认值
- 全局配置默认值:通过在配置文件中定义全局属性值
- 实例默认值:通过代码为实例定义的默认值
- 实例配置属性:通过配置文件来为指定的实例进行属性配置
1)、command属性
1)execution.isolation.strategy
:该属性用来设置HystrixCommand.run()执行的隔离策略,有如下两个选项
- THREAD:通过线程池隔离的策略。它在独立的线程上执行,并且它的并发限制受线程池中线程数量的限制(默认值)
- SEMAPHORE:通过信号量隔离的策略。它在调用线程上执行,并且它的并发限制受信号量计数的限制
全局配置属性:hystrix.command.default.execution.isolation.strategy
实例默认值:
@HystrixCommand(commandProperties = {@HystrixProperty(name = "execution.isolation.strategy",value ="SEMAPHORE")})
实例配置属性:hystrix.command.HystrixCommandKey.execution.isolation.strategy
2)execution.isolation.thread.timeoutInMilliseconds
:该属性用来配置HystrixCommand执行的超时时间,默认值为1000毫秒。当HystrixCommand执行时间超过该配置值之后,Hystrix会将该执行命令标记为TIMEOUT并进入服务降级处理逻辑
全局配置属性:hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds
实例默认值:
@HystrixCommand(commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")})
实例配置属性:hystrix.command.HystrixCommandKey.execution.isolation.thread.timeoutInMilliseconds
3)execution.isolation.semaphore.maxConcurrentRequests
:当HystrixCommand的隔离策略使用信号量的时候,该属性用来配置信号量的大小(并发请求数,默认为10)。当最大并发请求数达到该设置值时,后续的请求将会被拒绝
全局配置属性:hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests
实例默认值:
@HystrixCommand(commandProperties = {@HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests", value = "10")})
实例配置属性:hystrix.command.HystrixCommandKey.execution.isolation.semaphore.maxConcurrentRequests
2)、threadPool属性
1)coreSize:该参数用来设置执行命令线程池的核心线程数,该值也就是命令执行的最大并发量(默认值为10)
全局配置属性:hystrix.threadpool.default.coreSize
实例默认值:
@HystrixCommand(commandKey = "helloKey", threadPoolProperties = {@HystrixProperty(name = "coreSize", value = "10")})
实例配置属性:hystrix.threadpool.HystrixThreadPoolKey.coreSize
2)maxQueueSize:该参数用来设置线程池的最大队列大小。当设置为-1时,线程池将使用SynchronousQueue实现的队列,否则将使用LinkedBlockingQueue实现的队列(默认值为-1)
全局配置属性:hystrix.threadpool.default.maxQueueSize
实例默认值:
@HystrixCommand(commandKey = "helloKey", threadPoolProperties = {@HystrixProperty(name = "maxQueueSize", value = "-1")})
实例配置属性:hystrix.threadpool.HystrixThreadPoolKey.maxQueueSize
配置总结如下:
配置项(前缀hystrix.command.*.) | 含义 |
---|---|
execution.isolation.strategy | 线程THREAD或信号量SEMAPHORE隔离(默认值:THREAD) |
execution.isolation.thread.timeoutInMilliseconds | run()方法执行超时时间(默认值:1000) |
execution.isolation.semaphore.maxConcurrentRequests | 信号量隔离最大并发数(默认值:10) |
circuitBreaker.errorThresholdPercentage | 熔断的错误百分比阀值(默认值:50) |
circuitBreaker.requestVolumeThreshold | 断路器生效必须满足的流量阀值(默认值:20) |
circuitBreaker.sleepWindowInMilliseconds | 熔断后重置断路器的时间间隔(默认值:5000) |
circuitBreaker.forceOpen | 设true表示强制熔断器进入打开状态(默认值:false) |
circuitBreaker.forceClosed | 设true表示强制熔断器进入关闭状态(默认值:false) |
配置项(前缀hystrix.threadpool.*.) | 含义 |
---|---|
coreSize | 使用线程池时的最大并发请求(默认值:10) |
maxQueueSize | 最大LinkedBlockingQueue大小,-1表示用SynchronousQueue(默认值:-1) |
default.queueSizeRejectionThreshold | 队列大小阀值,超过则拒绝(默认值:5) |
推荐阅读:
https://segmentfault.com/a/1190000005988895