Spring Cloud Hystrix 熔断机制

Spring Cloud Hystrix,该框架的使用目标在于通过控制那些访问远程系统、服务和 第三方库的节点,从而对延迟和故障提供更强大的容错能力。

  • Hystrix具有服务降级、服务熔断、线程和信号隔离、请求缓存、请求合并以及服务监控等强大功能。
  • Hystrix能够很好解决“服务雪崩”的现象,进一步减短线程的占用的时间,避免请求被阻塞。
  • 通过在启动类添加 @EnableCircuitBreaker来开启熔断器功能

Hystrix的工作流程
1.创建HystrixCommand(单个结果)或HystrixObservableCommand(多个结果)对象 用来表示对依赖服务的操作请求,同时传递所有需要的参数;
(这里使用了命令模式 将事件通过命令的形式 委派特定对象执行)
2.命令执行 :有异步执行、同步执行、返回Observable事件源对象、返回多个Observable事件源对象这四种 事件源通常会被订阅者所监控
(这里的设计是观察者-订阅者模式)
3.结果是否被缓存 如果命中缓存,会即刻返回Observable事件源对象
4.判断断路器是否被打开 如果断路器被打开,执行fallback方法
5.线程池/请求队列/信号量是否占满 Hystrix的线程池设计采用了“舱壁模式”
6.HystrixObservableCommand.construct() 返回多个结果 或HystrixCommand.run() 返回单一的结果
7.计算断路器的健康程度
8.fallback处理:当服务执行失败时,“服务降级”,执行fallback函数
9.返回成功的响应:当Hystrix命令执行成功之后,它会将处理结果直接返回或者以Obervable的形式返回。

断路器健康程度
熔断器熔断服务的决定因素:
当前服务健康状态=请求失败数/请求总数 A
设定阈值 B
1.熔断器关闭 请求安全通过
2.A>B 请求安全通过
3.A<B 请求禁止通过

服务降级
如果设置fallback方法,进入fallback方法
通过fallback给用户一个友好的提示结果

“舱壁模式”
“舱壁模式”:Hystrix使用该模式实现线程池的隔离,它会为每一个依赖服务创建一个独立的线程池,这样就算某个依赖服务出现延迟过高的情况(线程被长时间挂起),也只会对该依赖服务的调用产生影响,而不会拖慢其他的依赖服务。这样的设计模式提高了应用的健壮性。
使用线程隔离为系统在稳定性和灵活性带来了巨大的提升,但是增加了线程池一定的额外开销。Hystrix在部分地方使用信号量的方式来控制单个依赖服务的并发度,但这种方式不支持设置超时和实现异步访问。

Hystrix的请求缓存
@CacheResult:该注解来标记请求命令返回的结果应该被缓存,它必须与@HystrixCommand注解结合使用
@CacheRemove:该注解来让请求命令的缓存失效,失效的定义根据KEY来设定 @CacheRemove(commadKey =“请求的函数名”)
@CacheKey:用来在请求命令的参数上做标记,作为缓存的key值,如果没有标注则会使用所有的参数。
@cacheKeyMethod:配置一个方法来指定Key生成方式 优先级高于CacheKey

//设置请求缓存
@CacheResult(cacheKeyMethod ="cachekey" )
@HystrixCommand(fallbackMethod = "helloFallback" )
public String helloService(@CacheKey("id") String id) { //@CacheKey("id")优先级低于cacheKeyMethod
ResponseEntity<String> responseEntity =restTemplate.getForEntity("http://springcloud-eureka-client-user/hello?id={1}",String.class,"luo");
return responseEntity.getBody();
}
//清空缓存
@CacheRemove(commandKey = "helloService")//获取请求命令的位置
@HystrixCommand(fallbackMethod = "helloFallback" )
public String removeService(String id) {
ResponseEntity<String> responseEntity =restTemplate.getForEntity("http://springcloud-eureka-client-user/hello?id={1}",String.class,"luo");
return responseEntity.getBody();
}
//设置缓存Key
public String cachekey(String id) {
return id;
}

请求合并
在高并发的情况下,会出现通讯消耗严重、排队和响应延迟的情况,为了进一步优化,Hystrix提供了HystrixCollapser来实现请求的合并,以减少通讯的消耗好线程的占用。
HystrixCollapser将使用一个合并处理器,将处于一个很短的时间窗(默认10毫秒)内对同一依赖服务的多个请求进行整合并以批量的方式发起请求的功能。
使用场景:
1.该请求本身就是一个高延迟的命令
2.一个时间窗口下会有很多请求(高并发)

@HystrixCollapser(batchMethod = "helloService",collapserProperties = {@HystrixProperty(name ="timerDelayInMilliseconds",value = "100")})

@HystrixCommand
@Override public List<User> helloService(List<String> ids) {
ResponseEntity<List> responseEntity =restTemplate.getForEntity("http://springcloud-eureka-client-user/hello?id={1}",List.class,StringUtils.join(ids,","));
return responseEntity.getBody();
}

Hystrix配置
Hystrix根据不同业务场景提供了非常丰富和灵活的配置方法。

@HystrixCommand(commandProperties = {@HystrixProperty(name="属性1",value = "值1"),@HystrixProperty(name="属性名2",value = "值2")})

提供了5类配置属性:
1.execution配置控制的是HystrixCommand.run()的执行。
2.fallback配置用来控制HystrixCommand.getFallback()的执行。这些属性同时适用于线程池的信号量的隔离策略。
3.circuitBreaker配置:断路器的属性配置,用来控制HystrixCircuitBreaker的行为。
4.metrics配置:HystrixCommand和HystrixObservableCommand执行中的指标信息。
5.requestContext配置:涉及HystrixCommand使用的HystrixRequestContext的设置。

Spring Cloud Hystrix 熔断机制_熔断机制