【问题标题】:Blocking I/O operation with WebFlux使用 WebFlux 阻塞 I/O 操作
【发布时间】:2019-03-27 11:50:57
【问题描述】:

我们有一个流程,我们希望使用 Spring Boot 2 WebFlux 通过响应式编程来实现。目前我们没有反应式编程的经验。
作为此流程的一部分,我们将创建一个或多个 HTTP 请求(我猜是使用 WebClient),并从 DB 中读取一些数据。
我们正在考虑使用 AWS DynamoDB,但据我了解 Java SDK 不支持反应式 API。
此读取将是阻塞 I/O 操作,我的问题是使用 WebFlux 实现此流程的一部分是否有好处?更一般地说,流程中的单个阻塞 I/O 操作是否会消除我们从使用响应式编程中获得的所有好处?

【问题讨论】:

    标签: java spring-boot reactive-programming nonblocking spring-webflux


    【解决方案1】:

    以下内容可能无法完全回答您的问题,但可能会有所帮助。 FAQ对于Spring Framework 5有一个问题,就是,

    如果我的数据库没有响应式库怎么办?

    答案是:

    处理混合阻塞和非阻塞代码的一个建议 将是使用微服务边界的力量来分离 来自非阻塞前端 API 的阻塞后端数据存储代码。 或者,您也可以使用工作线程池进行阻塞 操作,保持主事件循环不阻塞。

    我认为 Pivotal 的某个人可能是提供更多见解的合适人选。

    【讨论】:

    • 感谢您的回答。但是将阻塞的 I/O 操作移到另一个服务不会导致另一个服务出现瓶颈?
    • 把阻塞代码和非阻塞代码放在一起,总是会造成瓶颈。而另一方面,如果您将阻塞服务分开,它只会在从非阻塞服务调用时造成瓶颈。我就是这么想的。
    • 我明白了,但是对于每个请求,我们将调用其他服务以从数据库中获取数据。所以这个服务线程池将很快耗尽。
    【解决方案2】:

    根据您的问题,反应式是处理阻塞操作尤其是 IO(网络、文件等)的空闲方式

    您可以使用 library 以响应式方式实现此 api 或 wrap 使用响应式 api 的阻塞请求,这通常通过将阻塞操作放置在 anther 上来完成线程池

    在 spring webflux 中你可以实现类似的东西

    @GetMapping
    public Mono<Response> getResponse() {
      return Mono.fromCallable(() -> blockingOp())
        .publishOn(Schedulers.elastic());        
    }
    

    publishOn 在这种情况下会导致所有这些流程发生在另一个线程上,您可以选择专用线程池作为您的选择

    来自docselastic是一个

    动态创建基于 ExecutorService 的 Worker 并缓存线程池的调度程序,一旦 Worker 关闭就可以重用它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-24
      • 2015-02-24
      • 1970-01-01
      相关资源
      最近更新 更多