我对每个请求所属的线程模型的一些反应器概念有点困惑。我阅读了https://projectreactor.io/docs/core/release/reference但仍不清楚。让我们看一个例子:
@Autowired
UserRepository userRepository;
@GetMapping
Flux<User> findAll() {
log.info("findAll request arrived");
final Flux<User> defer = Flux.defer(() -> {
return Flux.fromIterable(userRepository.findAll());
});
return defer;
}
日志:[boundedElastic-4] - INFO - findAll 请求到达
在 Schedulers.boundedElastic 线程池中执行 GET 方法(根据文档用于 I/O 绑定工作)
@PostMapping
Mono<User> save(@RequestBody User user) {
log.info("save request arrived");
final Mono<User> newUser = Mono.fromCallable(() -> {
final User userMono = userRepository.save(user);
log.info("user saved!");
return userMono;
});
return newUser.subscribeOn(Schedulers.boundedElastic());
}
日志:[reactor-http-nio-6] - INFO - 保存请求到达
POST 方法落在http-nio线程池上。
@PostMapping("/test")
Mono<User> test() {
log.info("test");
return Mono.just(new User());
}
没有正文的 POST 也落在 Schedulers.boundedElastic 上。
@Bean
public ReactiveWebServerFactory reactiveWebServerFactory() {
NettyReactiveWebServerFactory factory = new NettyReactiveWebServerFactory();
final ReactorResourceFactory reactorResourceFactory = new ReactorResourceFactory();
reactorResourceFactory.setLoopResources(LoopResources.create("http-nio", 4, true));
reactorResourceFactory.setUseGlobalResources(false);
factory.setResourceFactory(reactorResourceFactory);
factory.setPort(8080);
return factory;
}
这就是我可以配置http-nio线程池的方式。
所以,我的问题是:
- 为什么带有 body 的 POST 方法会被http-nio线程池处理?
- 这个http-nio线程池应该是一个较小的线程池,那么为什么带有 body 的 POST 方法(我认为被认为是阻塞代码)落在了它们身上?
- 有意义返回 newUser.subscribeOn(Schedulers.boundedElastic()); 或者它应该保持在同一个线程上?