[关闭]
@zero1036 2019-03-25T11:08:34.000000Z 字数 5721 阅读 1240

熔断Hystrix

Java-其他库 架构


TG架构笔记


  1. 熔断
  2. 隔离
  3. 缓存

Hystrix执行逻辑

608A9B7F-DAE8-4CC4-8046-D5A75F2C23EE.png-200.3kB

熔断器Circuit Breaker

熔断器执行逻辑

7BB56A63-7958-4721-891E-287241159EB7.png-537kB

熔断器配置项清单

  1. //开启熔断器
  2. .withCircuitBreakerEnabled(true)
  3. //熔断器强制打开
  4. .withCircuitBreakerForceOpen(true)
  5. //熔断器强制关闭
  6. .withCircuitBreakerForceClosed(false)
  7. //默认值20.意思是至少有20个请求才进行errorThresholdPercentage错误百分比计算。
  8. // 比如一段时间(10s)内有19个请求全部失败了。错误百分比是100%,但熔断器不会打开,因为requestVolumeThreshold的值是20.
  9. // 这个参数非常重要,熔断器是否打开首先要满足这个条件。
  10. // 参考图实例【1】
  11. .withCircuitBreakerRequestVolumeThreshold(20)
  12. //设定错误百分比,默认值50%,例如一段时间(10s)内有100个请求,其中有55个超时或者异常返回了,
  13. // 那么这段时间内的错误百分比是55%,大于了默认值50%,这种情况下触发熔断器-打开。
  14. // 参考图实例【2】
  15. .withCircuitBreakerErrorThresholdPercentage(50)
  16. //半开试探休眠时间,默认值5000ms。当熔断器开启一段时间之后比如5000ms,会尝试放过去一部分流量进行试探,确定依赖服务是否恢复。
  17. //如果试探请求成功,熔断器关闭;如果失败,熔断器再次打开,继续等待下一个休眠窗口过去后再重试
  18. // 参考图实例【3】
  19. .withCircuitBreakerSleepWindowInMilliseconds(5000)

隔离

参考博文:http://www.coolxuewang.com/view/4

命令、分组、线程池Key

命令commandKey:默认情况下,命令名称来源于类名。Hystrix默认以commandKey作为信号量隔离的依据

分组groupKey:Hystrix使用命令分组将一起的命令进行管理,比如报告、警报、仪表盘或组/库。默认情况下,Hystrix使用 HystrixCommandGroupKey来定义命令线程池,除非单独定义线程池。

通过设置命令组, Hystrix会根据组来组织和统计命令的告警、仪表盘等信息。那么为什么一定要设置命令组呢?因为除了根据组能实现统计之外, Hystrix命令默认的线程划分也是根据命令分组来实现的。默认情况下, Hystrix会让相同组名的命令使用同一个线程池, 所以我们需要在创建 Hystrix命令时为其指定命令组名来实现默认的线程池划分。
如果 Hystrix的线程池分配仅仅依靠命令组来划分,那么它就显得不够灵活了,所以Hystrix还提供了 Hystrixthreadpoolkey来对线程池进行设置,通过它我们可以实现更细粒度的线程池划分。

线程池threadKey:线程池key,如果在没有特别指定Hystrixthreadpoo1Key的情况下,依然会使用命令组的方式来划分线程池。通常情况下,尽量通过Hystrixthreadpoolkey的方式来指定线程池的划分,而不是通过组名的默认方式实现划分,因为多个不同的命令可能从业务逻辑上来看属于同一个组,但是往往从实现本身上需要跟其他命令进行隔离

隔离策略

  1. 信号量
  2. 线程池
策略 有线程切换 支持异步 支持超时 支持熔断 开销大小 支持限流
信号量
线程池

信号量:

C6CBC35F-B735-4539-8FAC-225BD6469548.png-55.8kB

线程池

F3140775-E348-479E-8C27-143FB7C49760.png-50.8kB


缓存

重要:Hystrix缓存只能用于同一线程同一请求的上下,且不同线程间缓存不共享。so,其实比较鸡肋,有部分情况下可能有用。

官方建议:HystrixRequestContext.initializeContext()初始化是在filter中进行,但是每一次初始化之前的缓存就失效了,所以要测缓存,就只能在controller中调用两次,才能看到缓存的结果是否相同,在同一用户请求的上下文中,相同依赖服务的返回数据始终保持一致。

Spring体系中@CacheResult注解使用

  1. @Service
  2. public class CustomerService {
  3. @Autowired
  4. private RestTemplate restTemplate;
  5. @CacheResult(cacheKeyMethod = "getKey")
  6. @HystrixCommand(
  7. fallbackMethod = "goFallback",
  8. groupKey = "customerGroup",
  9. commandKey = "getCustomer")
  10. public String getCustomer(@CacheKey("id") String id) {
  11. RibbonMessage msg = restTemplate.getForObject("http://TG-RIBBON-SERVICE/ribbonAccept?id=" + id, RibbonMessage.class);
  12. System.out.println(msg);
  13. return msg.toString();
  14. }
  15. /**
  16. * 注意,@CacheRemove必须配合@HystrixCommand使用才有效果
  17. * @param id
  18. * @return
  19. */
  20. @HystrixCommand
  21. @CacheRemove(commandKey = "getCustomer", cacheKeyMethod = "getKey")
  22. public String clearCache(@CacheKey("id") String id) {
  23. return id;
  24. }
  25. public String getKey(String id) {
  26. return id;
  27. }
  28. public String goFallback(String id) {
  29. return "error:" + id;
  30. }
  31. }

Spring体系应用

  1. @HystrixCommand(
  2. fallbackMethod = "goFallback",
  3. groupKey = "customerGroup",
  4. commandKey = "getCustomer", commandProperties = {
  5. //超时
  6. @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "200"),
  7. //开启请求缓存
  8. @HystrixProperty(name = "requestCache.enabled", value = "true"),
  9. //设置熔断
  10. @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
  11. //断路器的最小请求数
  12. @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "1"),
  13. //休眠时间
  14. @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "200"),
  15. //断路频率
  16. @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")
  17. })
  18. public String getCustomer(String id) {}

常用配置汇总

通过properties配置

配置项 默认值 说明
hystrix.threadpool.default.coreSize 10 线程池启动时的固定大小值,还不是通常概念上的“最大值”,对于CPU密集型的任务,通常建议的线程池大小等于操作系统CPU核心数即可(一般是CPU数*2);针对IO密集型的任务,比如需要调用某个外部的http服务,并且每次调用时间比较长,可以适当调大该数值用更多的线程把这些等待时间利用起来。
hystrix.threadpool.default.maximumSize 50 最大线程数,超过coresize部分的线程在空闲一段时间后回回收
hystrix.threadpool.default.allowMaximumSizeToDivergeFromCoreSize true 是否让hystrix.threadpool.default.maximumsize配置生效
hystrix.threadpool.default.maxQueueSize 2000 线程等待队列大小,当任务数量超过配置的maximumSize时,多余的任务会进行等待队列,等待有线程空闲时执行;当设定的值为-1时,线程数量超过maximumSize的任务将会抛出异常。
hystrix.threadpool.default.queueSizeRejectionThreshold 1000 由于等待队列不能动态修改大小,所以引进了queueSizeRejectionThreshold配置来进行动态变更;queueSizeRejectionThreshold应当小于maxQueueSize,当需要等待的线程总数大于queueSizeRejectionThreshold时,即使没有达到maxQueueSize,依然会被拒绝进行等待队列,我们可以在运行时对该配置进行动态修改。
hystrix.threadpool.default.keepAliveTimeMinutes 1 当超出coreSize大小的线程空闲时间达到设定值时,将会被,回收。
hystrix.command.default.execution.isolation.strategy THREAD hystrix的隔离策略,可以使用线程池或者信号量模式,因为信号量是阻塞式的,推荐使用线程池。
hystrix.command.default.execution.isolation
.thread.timeoutInMilliseconds
1000 hystrix任务执行超时时间,应当大于ribbon设置的连接超时时间与读超时时间的和,但不应该太大。
hystrix.command.default.execution.timeout.enabled true 是否启用任务超时设置,推荐使用,防止任务一直等待,无法释放资源。
hystrix.command.default.execution.isolation
.thread.interruptOnTimeout
true 当任务执行时间已经超过设定的超时事件时,是否中断执行请求的线程的工作,推荐使用。
hystrix.command.default.execution.isolation
.thread.interruptOnCancel
false 当请求服务的主线程被中断或取消的时候,是否中断执行请求的线程的工作。
hystrix.command.default.fallback.enabled true 是否启用hystrix fallback功能。
hystrix.command.default.fallback.isolation
.semaphore.maxConcurrentRequests
10 当请求失败的数量达到设定的该数值时,将会直接拒绝接下来一段时间内的所有请求;可根据服务的承载量自行设定
hystrix.command.default.circuitBreaker.enabled true 是否启用hystrix断路器功能。
hystrix.command.default.circuitBreaker
.requestVolumeThreshold
20 进行hystrix离合器判定的最小请求数量,即只有当请求的数量达到设定的值时,才会进行判定是否开启断路器。
hystrix.command.default.circuitBreaker
.sleepWindowInMilliseconds
5000 当断路器开启以后时间达到设定的数值时,会尝试关闭断路器,重新请求服务,如果请求成功,断路器将会保持关闭状态;否则会重新开启断路器。
hystrix.command.default.circuitBreaker
.errorThresholdPercentage
50 当请求的失败比例达到设定值时,会开启断路器。
hystrix.command.default.circuitBreaker.forceOpen false 是否强制开启断路器,置为true时,断路器将一直保持开启状态,并拒绝所有服务。
hystrix.command.default.circuitBreaker.forceClosed false 是否强制关闭断路器,置为true时,断路器将一直保持关闭状态,不管请求的失败比例有多大。
hystrix.collapser.default.requestCache.enabled true 在批处理请求中是否启用缓存。
hystrix.collapser.default.maxRequestsInBatch Integer.MAX_VALUE 当批处理请求中的请求总数达到设置的值时会触发批处理请求,默认为无限大,通过下面的配置触发请求
hystrix.collapser.default.timerDelayInMilliseconds 10 当批处理请求被创建该时间值以后,会触发执行。

监控
https://hot66hot.iteye.com/blog/2155036

隔离策略最好的解释
https://blog.csdn.net/heyutao007/article/details/51006694

spring @CacheResult缓存示例:
https://www.cnblogs.com/wanggangblog/p/8550218.html

有提及缓存的策略,但未确定正确性
http://www.cnblogs.com/hellxz/p/9056806.html

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注