首页 > 解决方案 > 在 Spring Webflux Annotated 控制器中的不同线程中运行任务

问题描述

我有一个 Spring Webflux Annotated 控制器,如下所示,

 @RestController
public class TestBlockingController {

  Logger log = LoggerFactory.getLogger(this.getClass().getName());

  @GetMapping()
  public Mono<String> blockForXSeconds(@RequestParam("block-seconds") Integer blockSeconds) {
    return getStringMono();
  }

  private Mono<String> getStringMono() {
    Integer blockSeconds = 5;
    String type = new String();
    try {
      if (blockSeconds % 2 == 0) {
        Thread.sleep(blockSeconds * 1000);
        type = "EVEN";
      } else {
        Thread.sleep(blockSeconds * 1000);
        type = "ODD";
      }
    } catch (Exception e) {
      log.info("Got Exception");
    }
    log.info("Type of block-seconds: " + blockSeconds);
    return Mono.just(type);
  }
}

如何让 getStringMono 在与 Netty 服务器线程不同的线程中运行。我面临的问题是,当我在服务器线程中运行时,吞吐量基本上会减少(每秒 2 个请求)。如何在单独的线程中运行 getStringMono。

标签: spring-bootspring-webfluxproject-reactor

解决方案


您可以使用subscribeOn运算符将​​任务委托给不同的线程池:

Mono.defer(() -> getStringMono()).subscribeOn(Schedulers.elastic());

不过,您必须注意,在响应式应用程序中应不惜一切代价避免这种类型的阻塞。如果可能,请使用支持非阻塞 IO 并返回承诺类型(Mono、CompletableFuture 等)的客户端。如果您只是想人为延迟,请Mono.delay改用。


推荐阅读