spring-boot - 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 发布者事件期间复制上下文,但似乎在这样做的过程中失去了一些功能。例如,信号上下文丢失。
我需要一个适当的解决方案来解决这个问题:
- 一个可以在 MDC 和反应堆之间建立联系的库?
- 一种调整反应器/弹簧以透明地实现它的方法?
- 有什么建议吗?
解决方案
“我还没有找到令人满意的解决方案。”
使用上下文是目前唯一的解决方案。因为正如您所说,threadlocals 违背了与反应式编程有关的一切。在请求期间使用本地线程作为存储点是一种解决问题的资源繁重的方式,并且在我看来设计不佳。除非日志框架自己想出更好的解决方案来解决这个问题,否则我们开发人员必须通过上下文传递数据以适应日志框架的阻塞性质。
反应式编程是编程世界的一种范式转变。其他使用线程本地回滚事务的数据库驱动程序也遇到了大麻烦。JDBC 数据库驱动程序规范被定义为本质上的阻塞,而 atm。spring 和 R2DBC 项目已经尝试定义一个新的 JDBC 驱动程序规范,该规范本质上是非/阻塞的。这意味着所有供应商都必须从头开始重写他们的数据库驱动程序实现。
反应式程序是如此新,以至于许多库需要重写整个代码库。我们所知道的日志框架需要从头开始重写,这是一项艰巨的任务。而响应式中的上下文实际上甚至不应该出现在响应式编程中,它的实现只是为了适应 MDC 问题。
实际上需要在线程之间传递数据的开销很大。
所以,我们能做些什么?
- 推动日志框架,和/或帮助日志框架重写其代码库
- 接受没有“调整”可以神奇地解决这个问题
- 使用博文中建议的上下文和方式
推荐阅读
- html - 框架集不能在 EDGE 中运行,但运行良好 Mozilla/IE
- python - 通过make启动时,有什么方法可以查看shell脚本的输出,对于SAM
- java - 基于存储对象的属性修剪 flink 状态
- c++ - 避免隐式捕获这个?
- c# - Simple.OData.Client 错误:类型上不存在属性“上下文”
- spring-boot - 类星体纤维在线程启动后返回空结果
- java - 来自守护程序的错误响应:在等待连接时取消请求(等待标头时超出 Client.Timeout)
- python - 尝试使用 python AWS CDK 创建空堆栈时返回 JSII 错误
- python - Python如何在系列系列上应用每列平均值
- python - 使用来自另一个 docker 容器的 python 包