【问题标题】:Is Retrofit Reactor Adapter making calls nonblocking?Retrofit Reactor Adapter 是否会进行非阻塞调用?
【发布时间】:2020-11-07 22:28:57
【问题描述】:

我正在服务器上使用带有 Reactor 适配器的 Retrofit。我认为它允许我通过简单地使用 Mono 进行改造并将其以 Mono 的形式暴露给 Spring Boot 来解除阻塞(两者之间的所有操作都是响应式的)。

但是我注意到,当我尝试向另一个服务运行一些请求时,该服务内部有一些长时间的操作(需要几秒钟),我的服务看起来像是阻塞了某个线程,就像在适当地进行几个快速调用时一样配置它可能会导致重新启动我的服务(它应该只等待另一个服务响应,并且它接收的数据集很小)。还有一些跟踪工具让我认为我的线程在等待响应时很忙。

我试图找到一些关于此的文档,并查看了一些 OkHttp 和 Okio 代码,但我找不到任何可以使它成为非阻塞的部分,而且它看起来像是阻塞的。

在我的改造配置中我可能会遗漏哪些东西可以使我的呼叫无阻塞,或者也许有人知道没有办法让改造以这种方式工作?或者只是我误解了一些数据,默认情况下它应该是非阻塞的?

我在我的 Retrofit 构建器中添加了这样的设置方法来启用 Reactor:

addCallAdapterFactory(ReactorCallAdapterFactory.create())

【问题讨论】:

    标签: spring-boot retrofit2 okhttp nonblocking reactor


    【解决方案1】:

    OkHttp 大致遵循每个连接模型的线程。因此,对于 HTTP/2 服务器,单个连接可以通过一组固定的池连接和线程支持可变数量的请求。

    call.execute() 将被阻塞。

    call.enqueue(...) 将是非阻塞的,但在内部使用线程,并以阻塞模式从套接字读取。这是对客户端隐藏的,但 OkHttp 不使用 Java NIO。

    【讨论】:

    • 感谢您的回答!您能否提出一些替代方案,在等待响应时解锁线程。据我检查Okio打开一个流并等待,而另一种解决方案是首先检查流中是否有一些数据,如果没有,则等待而不阻塞,所以似乎应该有这样的解决方案。顺便提一句。我真的不明白那个non blocking 架构的好处是什么,除了它很容易并行运行......
    • 我不想在具体问题之外提供建议。如果你有 kotlin 协程或基于反应流的架构,那么通常你可以使用 OkHttp 和 call.enqueue。 Schedulers.IO 实际上是相同的方法,分配一个线程空闲等待来自网络的响应。根据您的工作负载,您可以使用基于 Netty 的微调解决方案,使用有限数量的线程扩展到多个连接。对于典型的移动或相对平静的内部服务器,OkHttp 模型的简单性可能是一个很好的权衡。
    • 其实问题是这样的,reactor 只是 Spring 的 RX 解决方案,看起来即使我使用它,线程也很忙。所以基本上 RX 唯一做的就是在线程之间切换,所以基本上当你使用 RX Single 并认为它会使你的代码非阻塞时,实际上它只是同步阻塞调用,因为 OkHttp 实现...... RX 唯一的好处或协程在 Retrofit 中提供了更好的并行调用处理 + 切换 Android 的主/网络线程。但是等待响应时线程总是很忙。
    猜你喜欢
    • 2020-10-28
    • 1970-01-01
    • 1970-01-01
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 2020-02-16
    相关资源
    最近更新 更多