在我的springboot应用程序中,我用HystrixCommand注释包装一个代码块,以指示该代码块受保护。
另外我正在使用THREAD作为hystrix执行隔离策略。由于代码块在单独的线程中运行(hystrix- {受保护方法的commandKey} -x),我通过编写自定义HystrixCommandExecutionHook在所有日志中添加唯一ID来注入MDC,从而使调试更加容易。并且在应用启动时,我已经注册了自定义插件。

我正在HystrixCommandExecutionHook的onStart()方法中初始化HystrixRequestContext。



在代码块中,在调用再次在单独的hystrix线程上运行的远程服务之前,我还调用了缓存服务。我通过从日志中检查线程名称(hystrix- {cacheService的commandKey} -x)来了解这一点。


@Override
 public <T> void onStart(HystrixInvokable<T> commandInstance) {
   HystrixRequestContext.initializeContext();
   Map<String, String> originalMDCContext = MDC.getCopyOfContextMap();
   if (originalMDCContext != null && !originalMDCContext.isEmpty()) {
      mdcContextVariable.set(originalMDCContext);
    }
  }


我面临的挑战是,当对缓存服务的调用完成并且控制权回到代码块的下一行时,HystrixRequestContext.getContextForCurrentThread()的值将为null。我看到HystrixRequestContext.isCurrentThreadInitialized()将具有FALSE值。如果代码块引发异常,则对NPE的onExecutionFailure方法中的清理将失败。清理代码如下:


private void cleanup() {
  HystrixRequestContext.getContextForCurrentThread().shutdown();
}


由于我在HystrixRequestContext.getContextForCurrentThread()中获取的是null,因此cleanup()在NPE上在executionSuccess / executionFailure上失败。

有人可以说明一下这里发生的事情吗?从其他服务调用返回后,为什么HystrixRequestContext.getContextForCurrentThread()变为null或为什么HystrixRequestContext.isCurrentThreadInitialized()变为false?

解决方法

当前,我正在检查清理方法,如果HystrixRequestContext.isCurrentThreadInitialized()为TRUE,然后调用shutdown()方法。如果为假,则不执行任何操作。

private void cleanup() {
if(HystrixRequestContext.isCurrentThreadInitialized() == Boolean.TRUE)
  HystrixRequestContext.getContextForCurrentThread().shutdown();
}


预期

我希望HystrixRequestContext.getContextForCurrentThread()应该包含状态(不应为null),直到我手动对其调用shutdown()为止。

实际

从其他服务返回调用后,HystrixRequestContext.getContextForCurrentThread()为空

最佳答案

请为使用hystrixCommand的服务以及调用cleanup()方法的位置提供一些伪代码,以便可以复制NPE

10-07 12:35