我正在使用基于注释的Spring WebFlux(Reactor Netty)开发Web服务器。 该服务器调用阻塞操作(JDBC)。 我尝试将每个阻塞操作切换到 Reactor 提供的“弹性调度程序”。
@RestController
@RequiredArgsConstructor
@RequestMapping("/member")
public class MemberApiRestController {
private final MemberService memberService;
@GetMapping("/all")
public Mono<List<String>> findAllMembers() {
return Mono
.fromCallable(()->memberService.findAll())
.map(member::toString)
.subscribeOn(Schedulers.elastic())
.publishOn(Schedulers.elastic())
}
}
public class MemberService {
public List<Member> findAll() {
log.debug("Blocking Operation...")
//Blocking - Operation.
}
}
log is like ...
2019-05-16 10:26:58,227 |-LOCAL [reactor-http-nio-7] TRACE o.s.web.server.adapter.HttpWebHandlerAdapter: 87 - [165a3273] HTTP GET "/member/all", headers={masked}
2019-05-16 10:26:58,249 |-LOCAL [elastic-20] DEBUG MemberService: 36 - Blocking Operation...
2019-05-16 10:27:00,277 |-LOCAL [reactor-http-nio-7] TRACE o.s.web.server.adapter.HttpWebHandlerAdapter: 87 - [165a3273] Completed 200 OK, headers={masked}
因为memberService.findAll()方法是阻塞操作,所以我切换到Schedulers.elastic()。
该方法在调度程序上调用。然而,最终的响应过程是在reactor-http-nio线程上。
这似乎是一个阻塞模型(reactor-http-nio 线程被阻塞,直到弹性线程工作完成。)。在我看来,如果它支持非阻塞 IO 线程模型,那么当您将上下文扔给其他调度程序时,剩余的工作将在那里处理。
是否可以切换响应处理程序调度程序? 如果不可能的话,我就能理解为什么他们要这样设计。
最佳答案
我的测试代码犯了一个错误。 我使用 RestTemplate 来发出请求。 我错过了 RestTemplate 实例的 Factory 对象对并发最大请求的限制。 (默认情况下,最大请求为 5。)。 固定最大请求数后,效果很好。
关于java - Spring WebFlux 无法将阻塞操作切换到结果中的其他调度程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56159932/