Netty 或任何其他非阻塞 IO 服务器上的 Logback MDC

Logback MDC on Netty or any other non-blocking IO server

Logback MDC(映射诊断上下文)正在利用 threadLocal(据我所知),以便在同一线程执行的所有日志语句上都可以访问它。

我的问题是,logback MDC 是否会像 Netty 或 Undertow 这样的非阻塞 IO 服务器端运行时工作,因为它曾经在 tomcat 中工作? 如果是,它是如何工作的,因为 Netty/Undertow 不像 tomcat.

不遵循每个请求一个线程

我正在尝试在 MDC 中放置一个 traceID,这样我就可以在 Splunk/ELK[=10= 这样的集中式日志系统中从多个 microservices/pipeline-listeners 的一个事务跟踪中跟踪我的所有日​​志]

我不是很熟悉直接使用 netty,但我知道可以使用带有异步代码的 logback MDC。但这并不容易。

基本上您需要以某种方式将 traceId 绑定到 request/connection,并且每次您开始处理该连接时,在 MDC 中为当前线程设置 traceId。

如果您正在使用线程池,您可以使用自定义执行器执行此操作,该执行器从当前线程本地存储中获取当前状态(例如 traceId),并创建一个包装的 Runnable 或 Callable 来设置线程本地存储运行 之前检索到的值。然后将包装的可运行对象转发给委托执行器。

你可以在这里看到这是如何完成的:https://github.com/lucidsoftware/java-thread-context/blob/master/thread-context/src/main/java/com/github/threadcontext/PropagatingExecutorService.java

事实上,根据您的需要,您也许可以使用那个 java-thread-context 项目。

正如您所提到的,MDC 实现基于 ThreadLocal,因此它并不真正适用于 Reactor。

如果使用 Reactor(我假设您是通过标签使用它),我建议的是:

  1. 使用 Context (docs here)MonoFlux 中可用,以便存储 traceId 在执行.

  2. 如果您正在使用 Spring-Webflux 并且您想要生成 tradeId 并将其添加到 Context 的一个地方,那么您可以使用 WebFilter (docs here) 来做到这一点。

  3. 然后您可以使用一些自定义方法从上下文中检索数据 辅助方法,例如 example by Nicolas Portman,或者创建您自己的自定义日志记录格式,您可以在其中使用来自 Context.
  4. 的数据