Spring Reactor WebClient 是如何实现非阻塞的?

use*_*332 5 project-reactor reactor-netty spring-webflux

基本问题:与 RestTemplate 相比,Spring Reactors WebClient 如何实现非阻塞?在将请求分派给外部服务(例如)之后,它是否不必在某处阻塞?HTTP 本质上是同步的,对吗?所以调用应用程序必须等待响应?线程如何知道对来自服务的响应做出反应的上下文?

Bri*_*zel 5

这里有几个单独的问题。

  • 如何管理 I/O 操作?
  • 这个运行时背后的线程模型是什么?
  • 应用程序如何处理 HTTP 背后的请求/响应模型?

在 Reactor 项目中WebClient,Netty 事件循环用于排队/调度/处理事件。每个读/写操作都是以非阻塞方式完成的,这意味着没有线程等待 I/O 操作完成。在此模型中,并发不是通过线程池完成的,但有少量线程处理永远不应该阻塞的工作单元。

从纯粹的 HTTP 角度来看(即,如果您捕获网络上的 HTTP 数据包),您会发现 aRestTemplate和 aWebClient调用之间没有太大区别。HTTP 传输本身不支持背压概念。因此,客户端仍然必须等待响应 - 此处的区别在于,使用该响应的应用程序WebClient不会浪费资源来等待该操作完成 - 它将使用它们来处理其他事件。

有关这方面的更多信息,请查看Reactor 参考文档中的响应式编程介绍以及Rossen Stoyanchev 的演讲,如果您习惯了典型的 Servlet 容器模型,它会很好地解释事情

  • 由于我对 Java NIO 的理解有限,我(概念上而非严格技术上)正确的说法是,将会有一些 SocketChannel 打开并使用 Selector 注册,然后由事件循环进行管理,该事件循环无限旋转以侦听选择器接收来自这些通道的事件,然后当通道发出事件时做出反应(调用等待响应的实际代码)? (2认同)