如何正确处理 Hystrix 回退中的预期错误?

Posted

技术标签:

【中文标题】如何正确处理 Hystrix 回退中的预期错误?【英文标题】:How to properly handle expected errors in Hystrix fallback? 【发布时间】:2016-05-26 14:32:15 【问题描述】:

我们有一个如下所示的 Hystrix (1.4.x) 命令(使用 Spring):

@HystrixCommand(groupKey = "GroupKey", commandKey = "CommandKey", fallbackMethod = "myFallback")
public List<X> findXs(long xId) 
   return externalService.findXsExternally(xId);

我们实际上不想从回退方法返回一个(空的)List,而是抛出一个异常,以便findXs 的调用者知道externalService 已关闭并可以采取相应的措施。但同时我们想利用 Hystrix 提供的功能。

在我们的例子中,我们希望调用者返回错误消息而不是返回列表。在 Spring 中,回退是这样实现的:

public List<X> myFallback(long xId) 
    // What to do?? Throw exception!?  

myFallback "works" 抛出异常,但 Hystrix 会警告我们:

CommandKey 失败,回退失败。

即它将将此解释为后备失败。在我们的例子中,异常应该被解释为回退失败,而应该被解释为预期的行为。我们还尝试将抛出的异常包装在 HystrixBadRequestException 中,但它似乎不适用于回退(根据 docs,这适用于“运行”方法)。

如何在 Hystrix 中实现抛出异常的回退方法?我们可以安全地忽略警告还是 Hystrix 不是这样设计的?

【问题讨论】:

【参考方案1】:

如果您不想使用回退,为什么还要设置它? Hystrix 不需要你设置一个。当您宁愿从缓存中返回陈旧数据而不是抛出异常时,将使用回退。这两种情况都算作 Hystrix 的失败。如果你从 fallback 方法中抛出异常,你只会混淆 Hystrix,它会认为除了服务本身之外你的 fallback 也有错误。如果你不提供回退,Hystrix 应该抛出一个 HystrixBadRequestException 来包装你的 findXs 方法抛出的异常。

【讨论】:

但是,如果您有多个使用 @HystrixCommand 注释的方法,您如何区分 HystrixRuntimeException 的来源?我有一个问题,我想根据哪个客户有不同的行为,例如超时,但我唯一知道的是发生了 HystrixRuntimeException。 注解中有一个叫commandKey的属性。你可以关闭它。我刚刚通过将其设置为 ckey 对其进行了测试,这是异常中的消息... ckey failed and fallback failed。异常内部可能还有更多方法,你自己试试看

以上是关于如何正确处理 Hystrix 回退中的预期错误?的主要内容,如果未能解决你的问题,请参考以下文章

CSS calc 在 Safari 和回退中不起作用

如何说 Hystrix 不会为 Hystrix 命令中的某些异常触发回退

在 Hystrix 中触发回退的自定义错误条件

聊聊Hystrix

Hystrix 回退方法返回 null

继续调用第 3 方,直到它返回 Hystrix 的预期响应