为什么ZUUL强制执行SEMAPHORE隔离以执行其Hystrix命令?

时间:2015-04-30 10:53:58

标签: spring-cloud netflix-zuul

我注意到Spring-Cloud ZUUL强制执行隔离到SEMAPHORE而不是THREAD默认值(根据Netflix的推荐)。

org.springframework.cloud.netflix.zuul.filters.route.RibbonCommand中的评论说:

  

我们希望默认为信号量隔离,因为这包装   另外2个已经线程隔离的命令

但我仍然不明白:-(那两个其他命令是什么?

以这种方式配置,Zuul只能扫描加载但不允许超时并让客户端离开。简而言之,即使Hystrix超时设置为1000毫秒,只有在转发到链中的服务的调用返回时(或者由于例如ReadTimeout而超时),才会释放客户端。

我试图通过覆盖配置来强制THREAD隔离(不幸的是,每个服务,因为代码中强制默认),一切似乎都按预期工作。但是,如果没有正确理解其含义,我并不热衷于这样做 - 当然关于代码中的注释以及Zuul的Spring Cloud版本采用的默认值。

有人可以提供更多信息吗? THX

2 个答案:

答案 0 :(得分:3)

Hystrix documentation有一个很好的例子,说明为什么在包装线程隔离的命令时信号量隔离是合适的。具体来说,它说:

  

façadeHystrixCommand可以使用信号量隔离,因为它正在进行的所有工作都是通过另外两个已经线程隔离的HystrixCommands。只要façade的run()方法没有进行任何其他网络调用,重试逻辑或其他“容易出错”的事情,就没有必要再使用另一层线程。

更新:问题提到必须为每个服务配置线程隔离,但我发现您可以通过设置以下属性来控制所有Hystrix命令(包括RibbonCommands)的隔离:

hystrix.command.default.execution.isolation.strategy = THREAD

答案 1 :(得分:0)

此模式在Hystrix文档中定义

  

立面的HystrixCommand可以使用信号隔离,因为它正在执行的所有工作都是通过另外两个已经是线程隔离的HystrixCommand。只要正面的run()方法没有执行任何其他网络调用,重试逻辑或其他“容易出错”的事情,就不必再有另一层线程。

我们仅使用信号量的原因是因为

  1. 我们希望限制对主要和次要(可能更多)的请求数量
  2. 由于隔离已经由实际的hystrix命令线程池(该外观代理服务器)实现,因此我们无需担心使用线程池在此级别进行隔离(池中的每个线程都有固定的资源消耗开销) ,而信号量只是一个计数器)。因此,轻量级的信号量就足够了

参考: https://github.com/Netflix/Hystrix/wiki/How-To-Use#primary--secondary-with-fallback