用网关zuul时,熔断hytrix里面的坑

1,zuul 默认的隔离级别是信号量,默认最大隔离信号量是100

信号量隔离和线程池隔离的区别如下:

https://my.oschina.net/u/867417/blog/2120713 

默认设置:

ba96054b67c3a20ba0479a5f7f4b9aa7d29.jpg

5e6462634a7250ea5162677cf60b154febe.jpg

 

 

2,zuul里隔离是按服务隔离的,也就是1个服务1个信号量,非接口级别的

所以得注意zuul服务本身的线程池大小,后端服务的线程池大小,以及隔离信号量或线程池的线程池大小,防止1个线程被占用光

 

3,在zuul里,重新封装了hytrix的一些配置名称,导致hytrix的一些原生配置会失效

具体设置hytrix参数的setter如下:

9e0964869e706ae15a52c2c035f010aaea5.jpg

需要通过zuulProperties重新设置的属性如下:

  • 隔离级别指定:zuul.ribbonIsolationStrategy: SEMAPHORE
  • 信号隔离的默认隔离大小:semaphore.maxSemaphores = 20
  • 指定服务的信号隔离级别大小:zuul.eureka.serviceId.semaphore.maxSemaphores = 20

而原生的hytrix.command.default.execution.isolation.strategy和maxConcurrentRequests的配置将失效,会被这3个覆盖

 

4,如果用的是信号量隔离级别,那么hytrix的超时将会失效

当使用线程池隔离时,因为多了一层线程池,而且是用的RXJava实现,故可以直接支持hytrix的超时调用

如果使用的是信号量隔离,那么hytrix的超时将会失效,但是ribbon或者socket本身的超时机制依然是有效果的,而且超时后会释放掉信号

252d06fc94f000dbb3e7d6bbebf89209a99.jpg

 

5,但如果是信号量隔离,依然得注意hytrix设置的超时时间,因为它涉及到信号量的释放

先看看hytrix信号量的实现:

信号量的设置在AbstractCommand里:

 

31b3b78380d8e6c56a17ed6d2c0ecc31a82.jpg

用了个ConcurrentHashMap<String, TryableSemaphore> 去保存个计数器的设置,key对应的是commandKey, TryableSemaphore(TryableSemaphoreActual)对应计数器实现,用java的AtomicInter实现,tryAcquire()时,进行原子加incrementAndGet,如果大于设置的maxConcurrentRequests,则进行阻塞

 

0979883998ad5f47c16a3670ee48601ae1c.jpg

返回fallBack;

执行完后,释放也很简单。原子减去,decrementAndGet。这样看来,信号量就是一个计数器。

那么为什么说和超时有关呢,因为超时时,即使访问线程还在阻塞,也会把当前信号量释放。(怎么做的,因为hytrix超时(此时访问线程并未超时)的后续处理部分是由RxJava控制,不是依靠访问线程的超时)

32d825eb60de4dee651a58627373f98281a.jpg

这句会造成,如果你配置了超时1s,如:

hystrix.command.default.execution.timeout.enabled=true

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=1000

那么你的信号量生效将是1s内,也就是说,过了1s,不管你socket是否超时,hytrix都会释放掉信号量

 

6,在zuul里,线程池隔离情况下,是异步访问的,而不是异步

这一点在上篇有说到,

fda407e692566b72fc8418ed9ce825e239a.jpg

调用的是hytrix command的excute方法,hytrix的官网原文说明如下:

  • execute() — blocks, then returns the single response received from the dependency (or throws an exception in case of an error)

execute是一个阻塞方法,也就是说,如果不合理的设置线程池的大小,和超时时间,还是有可能把zuul的线程消耗完。从而失去对服务的保护作用

 

总结:

zuul的复杂度很大程度因为集成了hytrix, ribbon,导致设置超时,线程,隔离都有一定的复杂度,本身文档确没那么清楚。

很多地方还是需要debug分析源码才能避免踩坑。

 

 

公众号:

0948edb526f45a71f6f42c334b60afaac8b.jpg

何锦彬 2018.09.25

 

 

 

 

 

 

 

转载于:https://my.oschina.net/u/867417/blog/2208600

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值