【问题标题】:Why is ZUUL forcing a SEMAPHORE isolation to execute its Hystrix commands?为什么 ZUUL 强制 SEMAPHORE 隔离来执行其 Hystrix 命令?
【发布时间】:2015-07-10 01:01:15
【问题描述】:

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

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

我们希望默认为信号量隔离,因为它包含 其他 2 个已经被线程隔离的命令

但我还是不明白 :-( 那另外两个命令是什么?

这样配置,Zuul 只能调度负载,但不允许超时,让客户端走开。简而言之,即使 Hystrix 超时设置为 1000 毫秒,客户端也只会在转发到链下服务的调用返回(或由于 ReadTimeout 导致超时)后才会释放。

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

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

【问题讨论】:

  • 有什么更新吗? RibbonCommand 中的 RestClient.LoadBalancerCommand 创建了 2 个 Observable。是否与此评论相关。我不确定。
  • 你好,很抱歉迟到了:) 我很好奇你为什么觉得有必要改变隔离策略?您是否注意到信号量导致的性能瓶颈?正如org.springframework.cloud.netflix.zuul.filters.route.support.AbstractRibbonCommand 中的评论中提到的,超时由它包装的2 个方法处理。我猜其中之一是功能区命令,因此可以通过 ribbon.connectTimeoutribbon.readTimeout 设置超时

标签: spring-cloud netflix-zuul


【解决方案1】:

此模式在 Hystrix 文档中定义

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

我们之所以只使用信号量是因为

  1. 我们希望限制对主要和次要(可能更多)合并的请求数
  2. 由于实际的 hystrix 命令线程池(这个门面代理)已经实现了隔离,我们不需要担心使用线程池在这个级别的隔离(池中的每个线程在资源消耗方面都有固定的开销) ,不像信号量只是一个计数器)。所以,轻量级信号量就足够了

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

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

    • 但是在这种情况下,另外两个 HystrixCommands 是什么...找不到它们因此我的问题。
    • @BertrandRenuart 我没有研究过 Zuul 的实现,所以我没有这个问题的答案。
    • @BertrandRenuart 也许评论指的是在 LoadBalancerCommand 中使用 rx.Observable,它是通过 RibbonCommand 中的 RestClient 调用的。虽然我不得不承认,但我真的只是在这里猜测。
    • 无法将 SEMAPHORE 配置更改为 THREAD,它已硬编码在 org/springframework/cloud/netflix/zuul/filters/route/RestClientRibbonCommand.getSetter(String commandKey)
    • @WornOutSoles 我不同意,设置上面答案中指定的属性肯定会改变超时行为。我相信您指向的配置是所谓的“代码中的实例默认值”,它可以被“动态实例属性”覆盖。详情请见github.com/Netflix/Hystrix/wiki/Configuration
    猜你喜欢
    • 2016-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多