我知道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对本地主机的请求:端口/测试将接收以纯文本形式发送到服务器的内容
无论我放在哪里,我都尝试使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()
在不同的subscribeOn()
或Mono/Flux
上包含一个单独的publishOn()
可以完成我的工作想要
答案 0 :(得分:3)
这是您无法更改的事情-这只是链subscribeOn()
被调用之前链中的最后一个subscribe()
调用,因此,取决于WebFlux使用它想要的任何调度程序。在这种情况下,它看起来像是在NIO驱动的事件循环或类似事件中处理请求。
但是,您可以在链中包括一个flatMap()
呼叫,您可以 指定一个单独的subscribeOn()
,而不会覆盖。这可能是一个选择,具体取决于您的用例,因为您可以在flatMap()
调用中定义的发布者中完成大部分工作。