在我的 springboot 应用程序中,我使用 HystrixCommand 注释包装了一个代码块,以指示该代码块受到保护。
我还使用 THREAD 作为 hystrix 执行隔离策略。由于代码块在单独的线程(hystrix-{protected method's commandKey}-x)中运行,因此我通过编写自定义 HystrixCommandExecutionHook 来注入(inject) MDC,以在所有日志中添加唯一的 id 以使调试更容易。我已经在应用程序启动时注册了自定义插件。
我正在 HystrixCommandExecutionHook 的 onStart() 方法中初始化 HystrixRequestContext。
在代码块中,在调用远程服务之前,我还调用了缓存服务,该服务在单独的 hystrix 线程上再次运行。我通过检查日志中的线程名称(hystrix-{cacheService's 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 值。如果代码块引发异常,则 onExecutionFailure 方法中的清理会失败并出现 NPE。清理代码如下:
private void cleanup() {
HystrixRequestContext.getContextForCurrentThread().shutdown();
}
由于我在 HystrixRequestContext.getContextForCurrentThread() 中得到 null,cleanup() 在executionSuccess/executionFailure 上因 NPE 失败。
有人可以解释一下这里发生的事情吗?为什么从其他服务调用返回后,HystrixRequestContext.getContextForCurrentThread() 变为 null 或者为什么 HystrixRequestContext.isCurrentThreadInitialized() 变为 false?
解决方法
目前,我正在检查清理方法,如果 HystrixRequestContext.isCurrentThreadInitialized() 为 TRUE,然后调用 shutdown() 方法。如果为 FALSE,则不执行任何操作。
private void cleanup() {
if(HystrixRequestContext.isCurrentThreadInitialized() == Boolean.TRUE)
HystrixRequestContext.getContextForCurrentThread().shutdown();
}
预期
我希望 HystrixRequestContext.getContextForCurrentThread() 应该包含状态(不应该为 null),直到我手动调用它。
实际
HystrixRequestContext.getContextForCurrentThread() 在从其他服务调用返回后具有 null
最佳答案
请为hystrixCommand
服务以及调用cleanup()
方法的地方提供一些虚拟代码,以便可以复制NPE
关于java - HystrixRequestContext.getContextForCurrentThread() 变为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55556245/