繁体   English   中英

subscribeOn 在 ServerRequest 的 bodyToMono 上使用时不起作用

[英]subscribeOn not working when using it on ServerRequest's bodyToMono

我知道 subscribeOn 用于在订阅序列时切换执行线程,但我发现它不适用于 ServerRequest.bodyToMono/Flux

就像是

Flux.just(1,2,3)
          .doOnNext(integer -> log.info("test {}",integer))
          .subscribeOn(Schedulers.elastic())
          .subscribe();

将使执行线程发生变化

INFO 23313 --- [      elastic-2] c.a.p.m.f.service.router.TestService     : test 1
INFO 23313 --- [      elastic-2] c.a.p.m.f.service.router.TestService     : test 2
INFO 23313 --- [      elastic-2] c.a.p.m.f.service.router.TestService     : test 3

但让我困惑的是

假设我有一个 Spring WebFlux 路由器:

@Configuration
public class TestRouter {
    @Bean
    public RouterFunction<ServerResponse> testRouterFunction(TestService testService) {
        return route().path("/test", builder -> builder.nest(accept(MediaType.ALL),
          route -> route.PUT("/", req -> {
              Mono<String> valueMono = req.bodyToMono(String.class);
              return ServerResponse.ok().body(testService.test(valueMono), String.class);
          }))).build();
    }
}

和服务:

@Service
@Slf4j
public class TestService {
    public Mono<String> test(Mono<String> mono) {
        return mono
          .doOnSubscribe(subscription -> log.info("on subscribe"))
          .subscribeOn(Schedulers.elastic())
          .doOnNext(s -> log.info("received {}", s))
          .subscribeOn(Schedulers.elastic());
    }
}

基本逻辑是 http 将请求发送到 localhost:port/test 将接收它以纯文本形式发送到服务器的内容

我尝试让 doOnNext 在其他线程而不是 Spring WebFlux 的 NIO 线程上运行,无论我放在哪里

subscribeOn

执行线程始终是 NIO 线程:

INFO 23200 --- [ctor-http-nio-4] c.a.p.m.f.service.router.TestService     : on subscribe
INFO 23200 --- [ctor-http-nio-4] c.a.p.m.f.service.router.TestService     : received test

感谢@MichaelBerry @SimonBaslé,你们俩都帮了我很多,赞成你们的两个答案

简而言之,reactor-netty 将为 http 订阅覆盖 subscribeOn,使用flatMap() ) 在不同的Mono/Flux上包含单独的subscribeOn()publishOn()可以完成我想要的工作

这不是你可以改变的——只有在调用subscribe()之前链中的最后一个subscribeOn()调用是值得尊重的,所以 WebFlux 可以使用它想要的任何调度程序。 在这种情况下,它看起来像是在 NIO 驱动的事件循环或类似的情况下处理请求。

但是,您可以在链中包含一个flatMap()调用,您可以为此指定一个不会被覆盖的单独subscribeOn() 这可能是一个选项,具体取决于您的用例,因为您可以在flatMap()调用中定义的发布者中完成大部分工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM