spring-boot - 如何调试永远无法完成的 Mono

标签 spring-boot spring-webflux project-reactor

我有一个 Spring Boot 应用程序,其中包含复杂的 react 流(它涉及 MongoDB 和 RabbitMQ 操作)。大多数时候它是有效的,但是......

某些方法返回 Mono<Void> 。这是一个典型的多层模式:

fun workflowStep(things: List<Thing>): Mono<Void> =
    Flux.fromIterable(things).flatMap { thing -> doSomethingTo(thing) }.collectList().then()

比方说doSomethingTo()返回 Mono<Void> (它向数据库写入一些内容,发送消息等)。如果我只是将其替换为 Mono.empty()那么一切都会按预期进行,但否则就不会。更具体地说,Mono 永远不会完成,它会运行所有处理,但会错过最后的终止信号。所以东西实际上是写入数据库的,消息实际上是发送的,等等。

为了证明缺乏终止是问题所在,这里有一个有效的技巧:

val hackedDelayedMono = Mono.empty<Void>().delayElement(Duration.ofSeconds(1))
return Mono.first(
    workflowStep(things),
    hackedDelayedMono
)

问题是,我该如何处理永远不会完成的 Mono,以弄清楚发生了什么?我没有地方可以放置日志语句或制动点,因为:

  • 没有错误
  • 没有发出任何信号

我如何检查 Mono 正在等待完成什么?

ps。我无法使用简单的 Mono 工作流程在应用程序之外重现此行为。

最佳答案

您可以通过在 react 流中使用 log() 运算符来跟踪和记录流中的事件。这对于更好地了解应用程序中发生的事件非常有用。

Flux.fromIterable(things)
    .flatMap(thing -> doSomethingTo(thing))
    .log()
    .collectList()
    .then()

Chained inside a sequence, it peeks at every event of the Flux or Mono upstream of it (including onNext, onError, and onComplete as well as subscriptions, cancellations, and requests).

Reactor Reference Documentation - Logging a Sequence

Reactor 引用文档还包含其他有关调试响应式(Reactive)流的有用建议,可以在此处找到:Debugging Reactor

关于spring-boot - 如何调试永远无法完成的 Mono,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65904851/

相关文章:

spring - 如何在 Spring Reactor Web 应用程序中执行一系列操作并确保一个操作在下一个操作之前完成?

reactive-programming - 如何在响应式(Reactive) Spring WebClient 调用的错误部分抛出异常?

java - Spring boot @Scheduler 无法在 tomcat 上运行

java - 在 Spring 5 Webflux 中启用 CORS?

java - 在 WebClient 中处理异常抛出 io.netty.handler.timeout.ReadTimeoutException

java - 如何使用 Spring Boot 2.1 Webflux 定制 Netty?

java - 无法压缩通量并返回空值。我们如何丢弃传递到通量中的事件对?

java - Spring Boot JPA如何使用实体类从表中选择特定列?

spring - @DataMongoTest 正在创建一个空的 MongoTemplate

java - Spring Boot 不会将文件夹请求映射到 `index.html` 文件