RestServlet vs WebClient在基于Servlet的Web-MVC应用程序中的优势

时间:2018-08-21 17:23:21

标签: spring spring-mvc spring-webflux

我要在下面的声明中对黑体进行澄清(我提供了完整的段落仅供参考):

  

RestTemplate不适合在非阻塞应用程序中使用,因此Spring WebFlux应用程序应始终使用WebClient。 在大多数并发情况下,以及在构成一系列相互依赖的远程调用时,在Spring MVC中也应该首选WebClient

在这里找到:https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html

对于Spring MVC应用程序,使用WebClientRestTemplate有什么好处?与说WebClient配置了apache RestTemplateHttpClient并配置了正确的连接和套接字配置相比,PoolingHttpClientConnectionManager如何实现更高的规模?

2 个答案:

答案 0 :(得分:4)

WebClient是非阻塞的,而RestTemplate是阻塞/同步的。如果您将非阻塞WebFlux API与阻塞库一起使用,则实际上是将其转换为阻塞API。

考虑RestTemplate实际上为每个事件创建一个新的 Thread ,而WebClient创建一个 Task (就像在队列,这实际上是Reactor在幕后为您管理的内容)。 如果每个非阻塞任务都有一个阻塞调用来支持它,那么您很快就会饿死( Thread )(就像每个RestTemplate一样;请注意,委派给{{1 }}仍在阻止通话)。 另一方面,任务将由反应框架进行排队,并在您拥有适当的可用资源时执行。

为什么将WebClient与Spring MVC结合使用

WebClient是非阻塞的!您可以使用所有ConnectionManager功能(发布,订阅,反压等)。这有助于节省资源(即,您使用更少的线程和更少的内存),并且Reactor将允许您最大化使用未使用的线程。 这里的问题不是Spring MVC真正的“为什么我应该使用WebClient”,而是我的应用程序中的“为什么我应该使用反应/非阻塞”框架。互联网上有很多有关此问题及其答案的示例(here's one

如果要使用非反应性非阻塞构造,

FluxMono也可以返回Java 8 CompletableFuture

为什么将WebClient与WebFlux一起使用

在您的referenced in that documentation页面上查看此报价:

  

WebClient 使用与 WebFlux 服务器应用程序相同的编解码器,并且   共享一个通用基本程序包,一些通用API和基础结构   服务器功能的Web框架。该API公开了Reactor 助焊剂   和单声道类型

关键是Flux使用与WebClient相同的反应式非阻塞类型。这就是为什么集成如此完美并且您获得出色的任务功能的原因。例如(并且我正在从that doc借用一小段代码):

Flux

看看这段代码如何产生WebClient client = WebClient.create("http://example.org"); Mono<Void> result = client.post() .uri("/persons/{id}", id) .contentType(MediaType.APPLICATION_JSON) .body(personMono, Person.class) .retrieve() .bodyToMono(Void.class); 吗? Mono建立在上的,这是一个反应式构造,这就是为什么要在框架中使用它。例如,您实际上可以return that Mono reactively in a Controller call

WebFlux

这类事情是他们说您应该在@PostMapping("/person") Mono<Void> create(@RequestBody Publisher<Person> personStream) { // ... above code could go here... return result; } 库中使用WebClient的关键原因。

答案 1 :(得分:0)

经过一些研究,我相信答案就在于Spring的DeferredResult。要从此blog中窃取一点文字,

  

DeferredResult是一个可能尚未完成的计算的容器,它将在将来提供。 Spring MVC使用它来表示异步计算,并利用Servlet 3.0 AsyncContext异步请求处理。

我相信发生在WebFlux之前的事情是这样,DeferredResult概念是在Spring MVC内部支持异步IO的第一个切入点,例如,现在已经弃用的AsyncRestTemplate返回了ListenableFuture包装器。

因此,这意味着如果我有一个相对简单的带有Spring MVC的REST API,我可能会返回一个DeferredFuture并通过WebClient异步生成其结果,从而获得异步的一些好处处理而不必迁移到Spring MVC(对于某些项目可能是不可行的)。