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

Spring boot 2.1.5, WebFlux, Reactor: How to deal properly with MDC

Spring 引导 2.1.5 反应堆项目 3.2.9

我正在使用上述框架设置一堆 rest 反应性 API,我 运行 遇到了 MDC(映射诊断上下文)的烦人问题。我的申请在 JAVA.

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

我 运行 遇到了与 Play Reactive 框架相同的问题,但通过透明地将映射上下文从一个参与者复制到另一个参与者找到了解决方法。

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

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

First - It works but forces you to use a bunch of utility methods

Same thing

Second - It tries to copy the context during the onNext publisher event but seems to lose some features on the way of doing that. The signal context, for example, is lost.

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

"I could not find a satisfying solution yet."

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

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

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

实际上需要在线程之间传递数据的开销很大。

那我们能做什么呢?

  • 推动日志框架,and/or帮助日志框架重写他们的代码库
  • 承认没有 "tweak" 可以神奇地解决这个问题
  • 使用博文中建议的上下文和方式

Project reactor context