Hystrix 命令不在 Hystrix 环境中运行

Posted

技术标签:

【中文标题】Hystrix 命令不在 Hystrix 环境中运行【英文标题】:Hystrix command does not run in Hystrix environment 【发布时间】:2018-07-15 15:20:44 【问题描述】:

我的 Hystrix 命令有问题。如果对 hystrix 包装方法的调用来自类内部,则 hystrix 包装方法不会在 Hystrix 环境中运行

在这种情况下,我将日志视为

05-02-2018 22:51:25.809 [http-nio-auto-1-exec-3] INFO  c.i.q.v.e.ConnectorImpl.populateFIDSchema -
    populating FID Schema

但是,如果我从类外部调用相同的方法,我会看到它在 Hystrix 环境中运行它

 05-02-2018 22:54:53.735 [hystrix-ConnectorImpl-1] INFO  c.i.q.v.e.ConnectorImpl.populateFIDSchema -
    populating FID Schema

我正在像这样用 HystrixCommand 包装我的方法

 @HystrixCommand(commandKey = "getSchemaCommand", fallbackMethod = "getSchemaCommandFallback")

有什么想法吗?

【问题讨论】:

【参考方案1】:

与@pvpkiran 的回答相反,这不是AspectJ 的限制,而是Spring AOP 的限制。 Spring AOP 是一种尝试通过代理实现 AspectJ 的 子集 的解决方案,而基于代理的方法是导致在未通过代理进行调用时不调用通知的原因 em>。

有关详细信息,请参阅 Spring 框架参考中的 Spring AOP capabilities and goals 和 AOP Proxies。

另一方面,AspectJ 直接修改被通知类的字节码,完全不涉及代理,并且不受基于代理的 Spring AOP 的限制。

AspectJ 在几乎所有方面都优于 Spring AOP,所以我建议你从 Spring AOP 切换到 AspectJ(你不需要为此放弃 Spring,因为 Spring 和 AspectJ 可以很好地协同工作)。

【讨论】:

您关于 Spring AOP 相对于 AspectJ 的自调用限制的陈述是正确的,我说得再好不过了。但是你也碰巧知道为什么 Spring AOP 应该在这里扮演任何角色吗?正如我在另一个答案下的评论中提到的,Hystrix 不使用开箱即用的 AOP。 @kriegaex 老实说,我对 Hystrix 并不是很熟悉,我只是看到了问题和另一个答案,然后说,嘿,这与关于 AspectJ 的每十个问题中的模式相同,因为人们很困惑他们实际上是在使用 AspectJ 还是 Spring AOP,或者这两种技术到底有什么关系。而且我们无论如何也无法从 OP 中弄清楚太多,因为它在他的 Spring 上下文中没有关于 Hystrix 的具体配置的任何细节。但他的问题很可能是上面的^^ :) 我也从未使用过 Hystrix。是的,也许@Pretty 使用了某种 Spring 插件。我们只能推测,直到他/她为他/她的问题添加更多细节。 @kriegaex 你绝对是对的,如果事实证明我的假设有误,我愿意更改/删除我的答案。 我认为您不需要这样做,因为它会证明是正确的答案。正如我所说,可能 OP 确实使用了某种 Spring 插件,她已经确认她正在使用 Spring。我的假设是使用来自 Hystrix 的“贡献”部分的 Hystrix-Javanica(基于 AOP,不像 Hystrix 核心),直接或间接通过 Spring Cloud Netflix 使用。前一个链接描述了如何使用 Spring AOP 或 AspectJ 配置 Javanica。【参考方案2】:

这是 Spring AOP 的一个限制(Hystrix-Javanica 是基于 AOP 的)。 当您在本地调用方法时,它不会通过代理,因此它不会真正在 Hystrix 环境中运行,而是像另一种方法一样运行。

但是,当您从课堂外拨打电话时,它会通过代理,因此可以正常工作。

许多其他功能也是如此。另一个例子是@Cacheable

当您从类外部调用时,Hystrix (Spring AOP) 会拦截调用并将其包装在自己的环境中。但是当你在本地进行通话时,它无法拦截通话。

【讨论】:

这是因为我使用的是 Spring 吗? 没有。这是因为 Hystrix 使用 AspectJ 来拦截调用。不是因为春天 @pvpkiran 此处正在讨论被拒绝的编辑meta.***.com/questions/362985/… 我认为这个答案是错误的,原因有两个:(1)根据Hystrix FAQ,该产品使用AOP。 (2) 即使它或它的插件模块之一确实使用了 AOP,AspectJ 也只是没有有答案中提到的关于自调用的限制,因为它不使用代理。该声明仅适用于 Spring AOP,但不适用于 AspectJ。 你来晚了,我已经在 Nándor 的回答下方的评论中提到了 Hystrix-Javanica。我还链接到有关如何使用 AspectJ 而不是 Spring AOP 配置它的描述。即使在您更新之后,您关于 AspectJ 是导致自调用问题的原因的说法过去和现在仍然是错误的。再次重申:AspectJ 不是问题,Spring AOP 才是。只需使用 AspectJ 并高兴,它会工作。我没有尝试就知道这一点,因为我知道 AspectJ 是如何工作的。恕我直言:Nándor 是对的,你错了。

以上是关于Hystrix 命令不在 Hystrix 环境中运行的主要内容,如果未能解决你的问题,请参考以下文章

javanica中的Hystrix异步方法不在spring-boot java应用程序中运行

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

Apache Camel 和 Hystrix 命令名称

使用环境变量设置 Hystrix 超时

聊聊Hystrix 命令执行流程

超时时需要清理的 Hystrix 命令