在我的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()的值将为空。我看到 HystrixRequestContext.isCurrentThreadInitialized()将具有 FALSE 值。如果代码块引发异常,则对NPE的onExecutionFailure方法中的清理将失败。清理代码如下:
private void cleanup() {
HystrixRequestContext.getContextForCurrentThread().shutdown();
}
由于我在 HystrixRequestContext.getContextForCurrentThread()中为空,因此 cleanup()在executeSuccess / executionFailure上由于NPE失败。
有人可以说明这里发生的事情吗?为什么 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()为空
答案 0 :(得分:0)
请使用hystrixCommand
和调用cleanup()
方法的位置为服务提供一些伪代码,以便可以复制NPE