当前位置: 首页 > 知识库问答 >
问题:

WebFlux使用WebClient阻止REST调用

羊舌墨一
2023-03-14

我有一种情况,我可以使用阻塞I/O库访问外部服务上的RESTendpoint,或者在这种情况下,我可以直接使用HttpClient(如WebClient)调用REST。现在,我想知道在包装对该库的调用和将其发布到弹性线程或使用WebClient访问endpoint之间是否存在性能差异。

如何准确地处理调用这两个选项。所以我们假设网络流量使用单线程来处理请求。然后,请求将由WebClient处理。这是否意味着线程或事件将被阻塞,直到请求接收到所有数据并将其传递回客户端?我还想知道EventLoop从哪里进来,它是与WebClient一起来的,还是已经在控制器/服务层。

这是我正在考虑使用的另一种方法,因为我已经有了通过OkHttpClient访问该endpoint的库。

Mono blockingWrapper = Mono.fromCallable(() -> { 
    return /* make a remote synchronous call */ 
});
blockingWrapper = blockingWrapper.subscribeOn(Schedulers.boundedElastic());

共有1个答案

闽焕
2023-03-14

当您在非网络流量应用程序中使用反应器时,例如在常规Spring网络应用程序中使用WebClient,反应器框架将启动一个单一事件循环来处理调度程序计划的所有事件。

另一方面,如果在完全反应式webflux应用程序中运行WebClient,则底层服务器将启动与主机上的内核数量相同的事件循环。

现在我们知道了,让我们从你们的例子开始。

如果您使用它,框架将启动一个带有线程池的调度程序,并且它可以随时自由切换调度线程。它可能使用一个线程调度flapMap,使用另一个调度线程调用restapi,它可以根据需要切换。当您阻塞或订阅时,您将线程留给框架,框架将尽可能地优化它所拥有的。

另一方面,如果您使用onSubcribe包装一个阻塞调用,那么当有人订阅(或阻塞)时,您基本上是在说,从定义的调度程序中选择一个线程,并在整个执行过程中使用该线程来调度事件循环

因此,最终得到的基本上与常规servlet应用程序的标准行为相同。

我个人的观点是使用webclient,因为reactor基本上是从您那里抽象出线程的,所以它可以尽可能地做好自己的事情,您可以专注于处理业务逻辑。基本上,您可以选择反应式编程,以获得尽可能简单的高度优化的异步非阻塞代码,而无需处理异步注释、锁、锁存、未来、线程池等。

 类似资料:
  • 如果类路径上有SpringWebFlux,还可以选择使用WebClient调用远程REST服务。与RestTemplate相比,这个客户端具有更多的功能感和完全的反应性。您可以在SpringFrameworkdocs中的专用部分中了解更多关于WebClient的信息。 Spring Boot为您创建并预配置WebClient.Builder; 强烈建议将其注入组件并使用它来创建WebClient实

  • 我希望以并行方式并使用无阻塞线程(如Python中的eventlet) 我想用这样的线程创建单独的共享工作线程池,以便不为每个传入请求创建一个共享工作线程池。 以下是有关调度器的文档http://projectreactor.io/docs/core/release/reference/#schedulers 但是我不能为每个请求创建新的工作池,池中的线程仍然以阻塞的方式工作。 如果有人用Spri

  • 我试图通过使用Java+Spring+WebFlux开始反应性编程。 当我在endpoint上调用时,我得到一个 下面是上的服务层 我还尝试删除和中的concinting,但没有成功。

  • 我试图使用WebClient实现以下场景。使用RestTemplate很琐碎,但我再也做不到了。

  • 问题内容: Ajax使用回调,因为它是同步的。 我希望对远程URL块的调用直到出现一些答案为止 ,就像在Ajax中一样,但是没有异步部分,或者我要说要进行JAX调用。 是否有任何技术可以使以下事情发生(使用JQuery)(…使用JQuery或其他解决方案): 我只是想知道-想学习。 实际上,有时会阻塞直到回复合适为止。我并不是说要浏览器阻止,而只是脚本运行时。 问题答案: 您可以在使用jQuery

  • 我正在使用webclient进行rest调用,我需要的是,如果主URL第n次失败,那么在次URL上进行下一次重试。请在下面找到我正在使用的逻辑的示例代码。但是似乎我们不能在创建后更改URL,即使我更改了URL,它也不会生效,仍然会将请求激发到初始URL。 有没有办法在重试周期中间更改URL?