【发布时间】:2022-01-02 14:53:39
【问题描述】:
如何使用 Spring Webflux + Netty + Reactor 从阻塞调度器(blocking-pool)切换回之前的调度器(reactor-http-nio)?
代码:
@RequiredArgsConstructor
@Service
@Slf4j
public class BookService {
private final IBookRepo bookRepo;
private final BlockingPoolConfig blockingPoolConfig;
public Mono<Optional<Book>> getBook(Long id) {
log.debug("getBook() - id: {}", id);
return asyncCallable(() -> {
log.trace("getBook() - invoking bookRepo.findById(id) ...");
return bookRepo.findById(id);
});
}
protected <S> Mono<S> asyncCallable(Callable<S> callable) {
return Mono.fromCallable(callable)
.subscribeOn(blockingPoolConfig.blockingScheduler());
}
}
@RestController
@RequiredArgsConstructor
@Slf4j
public class BookController {
private final BookService bookService;
@GetMapping("/book/{id}")
public Mono<Book> get(@PathVariable Long id) {
log.debug("get() - id: {}", id);
return bookService.getBook(id)
.publishOn(Schedulers.parallel()) //publishOn(... ?)
.map(optionalBook -> {
return optionalBook.map(book -> {
log.debug("get() result: {}", book);
return book;
}).orElseThrow(() -> {
log.debug("book with id: {} is not found.", id);
return new ResponseStatusException(HttpStatus.NOT_FOUND, "Book not found");
});
});
}
@Configuration
@Slf4j
public class BlockingPoolConfig {
@Value("${spring.datasource.maximumPoolSize:8}")
private int connectionPoolSize = 1;
@Scope("singleton")
@Bean
public Scheduler blockingScheduler() {
Scheduler scheduler = Schedulers.newBoundedElastic(connectionPoolSize, connectionPoolSize, "blocking-pool");
return scheduler;
}
}
上面我使用的是publishOn(Schedulers.parallel()),但是这个创建了新的线程池(并行)。而不是这个,我更喜欢切换 reactor-http-nio 线程池。
实际结果日志:
19:17:45.290 [reactor-http-nio-2 ] DEBUG t.a.p.controller.BookController - get() - id: 1
19:17:45.291 [reactor-http-nio-2 ] DEBUG t.a.p.service.BookService - getBook() - id: 1
19:17:45.316 [blocking-pool-1 ] TRACE t.a.p.service.BookService - getBook() - invoking bookRepo.findById(id) ...
19:17:45.427 [parallel-2 ] DEBUG t.a.p.controller.BookController - get() result: Book(id=1, title=Abc)
预期结果日志:
19:17:45.290 [reactor-http-nio-2 ] DEBUG t.a.p.controller.BookController - get() - id: 1
19:17:45.291 [reactor-http-nio-2 ] DEBUG t.a.p.service.BookService - getBook() - id: 1
19:17:45.316 [blocking-pool-1 ] TRACE t.a.p.service.BookService - getBook() - invoking bookRepo.findById(id) ...
19:17:45.427 [reactor-http-nio-2 ] DEBUG t.a.p.controller.BookController - get() result: Book(id=1, title=Abc)
【问题讨论】:
-
什么是 BlockingPoolConfig?
-
我添加了 BlockingPoolConfig 的来源
标签: spring-boot spring-webflux project-reactor reactor-netty