首页 > 解决方案 > Spring boot 2.1.5、WebFlux、Reactor:如何正确处理MDC

问题描述

Spring Boot 2.1.5 Project Reactor 3.2.9

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

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

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

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

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

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

一样

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

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

标签: spring-bootspring-webfluxproject-reactor

解决方案


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

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

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

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

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

所以,我们能做些什么?

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

项目反应堆上下文


推荐阅读