Spring中的HTTP请求后我们是不是需要清除MDC
Posted
技术标签:
【中文标题】Spring中的HTTP请求后我们是不是需要清除MDC【英文标题】:Do we need clear MDC after HTTP request in SpringSpring中的HTTP请求后我们是否需要清除MDC 【发布时间】:2017-07-13 20:51:27 【问题描述】:根据这个答案thread local variable,当我们使用线程本地时,我们应该清除线程池环境中的所有变量。
所以基本上我只想确认,当我们使用 MDC(映射诊断上下文)时,我们还应该清除 MDC 以了解内存泄漏,这是真的吗?
例如:
@Configuration
public class WebConfig implements WebMvcConfigurer
public class HttpInterceptor implements HandlerInterceptor
@Override
public boolean preHandle(final HttpServletRequest request,
final HttpServletResponse response,
final Object handler)
MDC.put(SESSION_ID, session_id);
@Override
public void postHandle(final HttpServletRequest request,
final HttpServletResponse response,
final Object handler,
final ModelAndView modelAndView)
MDC.clear(); //WE SHOULD CLEAR MDC.... if not memory leaks ?
@Override
public void addInterceptors(InterceptorRegistry registry)
registry.addInterceptor(new MdcHandlerInterceptor());
【问题讨论】:
我猜危险与其说是内存泄漏,不如说是一个请求无意中“继承”了前一个请求的 MDC 值。 【参考方案1】:您可以编写如下测试代码。
public static void request(ThrowingRunnable runnable, String para)
CompletableFuture.runAsync(() ->
MDC.put("var"+ para, "value"+ para);
try
runnable.runThrows();
catch (Exception e)
log.warn(e.getMessage(), e);
finally
// get MDC variables
String st = MDC.getCopyOfContextMap().entrySet().stream().map(e -> e.getKey() + "=" + e.getValue()).reduce((a, b) -> a + "," + b).orElse("");
log.info(st);
);
public static void main(String[] args) throws InterruptedException
for (int i = 0; i < 100; i++)
request(() ->
, i + "");
Thread.sleep(10000);
【讨论】:
【参考方案2】:MDC 是基于线程的,因此不可能在线程之间共享信息...只有在同一线程中有人再次使用 MDC-Values 时才会产生影响... 而当线程结束时,MDC的ThreadLocalMap就会消失……我猜……
【讨论】:
你不需要回答已经有答案的古老问题,尤其不应该用猜测来回答。如果您觉得我的回答有遗漏,请告诉我,我会详细说明。 危险在于请求由线程池处理,其中线程被重用并保留其先前的值。所以最好明确清除 MDC,这样处理请求的线程才能被重用。【参考方案3】:不是为了内存泄漏,而是为了防止在请求之间保留信息。您不希望您的第一个请求输入foo
,而您的第二个请求输入bar
,最终以foo
bar
而不仅仅是bar
。
当然,如果您总是只填写相同的确切值(如远程 IP 等),这不可能发生,但安全总比抱歉好。您不想记录不良信息。
注意:您放入一个请求的信息并不总是传播到下一个请求,因为它们可以在其他线程上执行,即使对于同一个端点。这就是为什么该问题可能会被忽略的原因,因为它不能可靠地重现,尤其是在您覆盖大部分值的情况下。
【讨论】:
以上是关于Spring中的HTTP请求后我们是不是需要清除MDC的主要内容,如果未能解决你的问题,请参考以下文章