Hystrix的作用
Hystrix的主要作用是在微服务环境下防止服务雪崩,确保服务弹性及可用性。
具体来说,Hystrix可以实现:
- 服务降级:通过fallback实现服务不可达情况下的服务降级作用。
- 熔断:服务不可达的情况下在设定时间窗口范围内熔断服务,快速fallback。
- 限流:通过信号量或线程池的模式实现限流,确保服务在流量高峰时的可用性。
Hystrix服务降级
前面文章我们已经分析过,通过@HystrixCommand注解实现服务降级:
@HystrixCommand(fallbackMethod = "fallback",commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000")
})
@HystrixProperty之execution.isolation.thread.timeoutInMilliseconds:指定Hystrix的服务超时判定时长,超过该时长则认为服务调用失败
fallbackMethod:服务调用超时或发生异常的情况下的fallback替代方法,也就是降级后的服务。
Hystrix熔断
官网熔断流程图:
熔断机制的含义是,在服务不可用的情况下,除了fallback提供服务降级之外,如果失败的调用达到设定的条件后,会触发断路开关打开,断路开关打开后,后续对失败服务的请求会被直接fallback,直到断路开关状态变更为半开半闭或闭合。
可以发现熔断的概念和电路保险熔断的概念一样:当电路中某一电器工作不正常后,会自动熔断保险丝断开电路,起到对该电器以及电路的保护,直到电器恢复正常后重新焊接保险丝后,电路才会正常工作。
Hystrix断路开关的状态:
- 闭合:默认为闭合状态,可以对服务正常调用。
- 打开:服务调用失败达到设定的阈值后打开,一定时间范围(MTTR 平均故障处理时间)内不会调用服务。打开时长达到MTTR设置的时间后,切换到半熔断状态(半开半闭)。
- 半开半闭:半熔断状态,此状态下允许请求访问服务一次,如果访问成功则关闭断路器,否则再次打开断路器。
默认情况下Hystrix的断路开关处于闭合状态,触发断路开关打开的条件是:在设定时间窗口范围内、请求次数达到设置次数、错误调用达到一定比例。
Hystrix断路器设置:
@HystrixCommand(fallbackMethod = "fallback", commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),//是否开启断路器
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),// 请求次数
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),// 时间窗口期
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")// 失败率达到多少后跳
})
断路器的重要参数:
circuitBreaker.sleepWindowInMilliseconds:时间窗口期
circuitBreaker.requestVolumeThreshold:请求次数
circuitBreaker.errorThresholdPercentage:请求失败的比例
circuitBreaker.circuitBreakerSleepWindowInMilliseconds:故障恢复时长。断路器打开状态下、本参数设置的时间窗口范围内的请求直接被fallback,之后的一次请求会被放行访问服务。如果访问成功则关闭断路器,否则再次打开断路器。
以上设置的含义是:在10秒的时间范围内,请求次数达到10次,并且请求失败的比例达到60%,则打开断路开关。
以上配置下,如果在10秒内连续请求某服务10次、错误6次,则打开断路器。
Hystrix限流
Hystrix提供两种方式的限流:
- 线程池
- 信号量
线程池限流
Hystrix允许通过@HystrixCommand注解设置当前服务的线程池:
@HystrixCommand(
groupKey="threadA",
threadPoolKey="threadA",
threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "20"),
@HystrixProperty(name = "maximumSize", value = "30"),
@HystrixProperty(name = "maxQueueSize", value = "20"),
@HystrixProperty(name = "keepAliveTimeMinutes", value = "2")
},commandProperties = {
@HystrixProperty(name = "execution.isolation.strategy",value = "THREAD")
每一服务的线程池单独设置、互不影响。
参数:
- “execution.isolation.strategy”:设置为“THREAD”指定限流方式为线程池。
- coreSize:线程池核心线程数。
- maximumSize:线程池最大线程数。
- maxQueueSize:最大队列数。
- keepAliveTimeMinutes:空闲线程最大存活时长。
采用线程池的方式可以实现有效限流,当并发请求大于maximumSize后,如果队列已满则立即fallback,否则请求会进入到队列排队等待线程释放后再执行。所以,在线程池控制下,并发请求数不会超过maximumSize。
信号量
@HystrixCommand(
fallbackMethod = "fallback",
commandProperties = {
@HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests",value = "100"),
@HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE"),
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "10000")
}
)
参数
- execution.isolation.strategy:SEMAPHORE通过信号量方式隔离
- maxConcurrentRequests:最大并发请求数