使用MDC或ThreadLocal

4

当使用http调用其他k8s服务时,我希望将从我的Nginx接收到的X-Request-Id传递给其他服务。

目前,我正在使用请求过滤器来捕获X-Request-Id头,并将其放入MDC中。

        final String nginxRequestId = requestContext.getHeaderString("X-Request-Id");
        if (nginxRequestId != null) {
            MDC.put("infra_request", nginxRequestId);
        }

现在,我正在k8s中调用服务B的端点(因此没有Nginx阻塞),并希望获取X-Request-Id以将其放入请求头中。这里有两个选项:

  1. 直接从MDC获取该值
  2. 将该标头存储在线程本地变量中(因为服务使用Dropwizard),除了将其存储在MDC中

我可能会使用MDC来完成它,但我不确定这是否是最佳实践,或者是否存在一些问题。


1
由于MDC使用了ThreadLocal,您从额外的ThreadLocal中将获得什么优势?只需确保在之后清理您的MDC - Kayaman
1
我的意思是,MDC 主要用于日志记录,所以我不确定这是否总是有效。 - Lukas Forst
2个回答

5

我曾经使用过MDC和ThreadLocal来传递交易ID到headers。在内部,MDC使用ThreadLocal,并且具有一些预定义的功能,例如向每个日志添加前缀。如果您要放置的数据具有业务用途,则建议使用ThreadLocal,否则可以选择MDC。


1
这正是我的当前方法 - 仅将MDC用于记录目的,但现在我想从中读取而不是仅用于日志记录 - 因此它具有某种业务用途,因此我正在考虑改用线程本地存储。然而,我不确定是否过度设计或只是更好的选择... - Lukas Forst
我认为你的方法没有任何问题。 - theNextBigThing

2

我认为对于你的目的来说,使用MDC是很好的选择。在内部,MDC使用ThreadLocal。即使你使用ThreadLocal,在更好的实现方式方面,你也需要将ThreadLocal变量包装在一个类中。而MDC则为你完成了这个操作。


但这带有一个警告,即如果您的代码记录了所有MDC数据,那么现在还将记录此附加数据,这可能是可以或必需的,具体取决于用例,例如在我的情况下不需要。 - Harsh Gundecha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接