Spring boot 2.1.5、WebFlux、Reactor:如何正确处理MDC

Arn*_*lle 8 spring-boot project-reactor spring-webflux

Spring Boot 2.1.5 项目反应堆 3.2.9

我正在使用上述框架设置一堆其余的响应式 API,并且遇到了 MDC(映射诊断上下文)的恼人问题。我的应用程序是在 JAVA 中。

MDC 依赖线程局部变量来存储当前查询的映射上下文以放入日志。显然,该系统并不完美,并且与响应式模式相矛盾,因为执行的不同步骤将通过不同的线程执行。

我在 Play Reactive 框架中遇到了同样的问题,但通过将映射上下文从一个演员透明地复制到另一个演员,找到了一种解决方法。

对于 spring 和 reactor,我还没有找到令人满意的解决方案。

在互联网上找到的一些随机示例:

首先 - 它有效,但迫使你使用一堆实用方法

一样

第二 - 它试图在 onNext 发布者事件期间复制上下文,但似乎在这样做的过程中丢失了一些功能。例如,信号上下文丢失了。

我需要一个适当的解决方案来处理这个问题:

  • 一个可以在 MDC 和 reactor 之间建立链接的库?
  • 一种调整反应器/弹簧以透明地实现它的方法?
  • 有什么建议吗?

Tho*_*olf 6

“我还没有找到令人满意的解决方案。”

使用上下文是目前唯一的解决方案。因为正如你所说的 threadlocals 违背了与反应式编程有关的一切。在请求期间使用线程本地作为存储点是一种资源繁重的解决方法,在我看来设计很差。除非日志框架本身为问题提供更好的解决方案,否则我们开发人员必须通过上下文传递数据以适应日志框架的阻塞性质。

响应式编程是编程世界的范式转变。其他使用线程本地回滚事务的数据库驱动程序也遇到了大麻烦。JDBC 数据库驱动程序规范在本质上被定义为阻塞,并且 atm。spring 和 R2DBC 项目已经尝试定义一个新的 JDBC 驱动程序规范,该规范本质上是非阻塞的。这意味着所有供应商都必须从头开始重写数据库驱动程序实现。

反应式程序是如此新,以至于许多库需要重写整个代码库。我们所知道的日志框架需要从头开始重写,这是一项艰巨的任务。而反应式中的上下文实际上甚至不应该出现在反应式编程中,它的实现只是为了适应 MDC 问题。

从线程到线程传递数据实际上需要很多开销。

所以,我们能做些什么?

  • 推动日志框架,和/或帮助日志框架重写他们的代码库
  • 接受没有“调整”可以神奇地解决这个问题
  • 使用博客文章中建议的上下文和方式

项目反应堆背景