春季最高

通过参考资料开始使用Spring 5和Spring Boot 2学习的春天课程:

> >学习春天
休息前

通过参考资料开始使用Spring 5和Spring Boot 2学习的春天课程:

>>查看课程

1.介绍

在本教程中,我们将比较Spring的两种web客户端实现创建RestTemplate以及新的Spring 5的反应性替代WebClient

2.阻塞与非阻塞客户端

在web应用程序中,对其他服务进行HTTP调用是一个常见的需求。因此,我们需要一个web客户端工具。

2.1。创建RestTemplate阻塞客户端

很久以来,春天一直在提供创建RestTemplate作为一个web客户端抽象。在引擎盖下,创建RestTemplate使用基于每请求一个线程模型的Java Servlet API

这意味着线程将阻塞,直到web客户机接收到响应。阻塞代码的问题是由于每个线程消耗了一定数量的内存和CPU周期。

让我们考虑有大量的传入请求,这些请求正在等待生成结果所需的缓慢服务。

等待结果的请求迟早会堆积起来。因此,应用程序将创建许多线程,这将耗尽线程池或占用所有可用内存。由于频繁的CPU上下文(线程)切换,我们还可能体验到性能下降。

2.2。WebClient非阻塞客户端

另一方面,WebClient使用Spring响应式框架提供的异步、非阻塞解决方案

创建RestTemplate为每个事件(HTTP调用)使用调用者线程,WebClient将为每个事件创建类似“任务”的东西。在幕后,反应性框架将对这些“任务”进行排队,并只在适当的响应可用时才执行它们。

响应式框架使用事件驱动的体系结构。它提供了通过。组成异步逻辑的方法反应流API。因此,与同步/阻塞方法相比,响应式方法可以在使用更少的线程和系统资源的情况下处理更多的逻辑。

WebClient春天WebFlux图书馆。因此,此外,我们还可以使用具有响应式类型的功能性、流畅的API (莫诺通量)作为陈述式作文

3.比较的例子

为了演示这两种方法之间的区别,我们需要在许多并发客户机请求的情况下运行性能测试。当客户端请求达到一定数量后,阻塞方法会显著降低性能。

另一方面,响应性/非阻塞方法应该提供恒定的性能,不管请求的数量是多少。

就本文而言,让我们实现两个REST端点,一个是using创建RestTemplate另一种是WebClient。它们的任务是调用另一个慢速REST web服务,该服务返回一个tweet列表。

首先,我们需要Spring Boot WebFlux启动器依赖:

<依赖> < groupId > org.springframework。启动< / groupId > < artifactId > spring-boot-starter-webflux < / artifactId > < / >的依赖

此外,下面是我们缓慢的服务REST端点:

@GetMapping("/slow-service-tweets") private List getAllTweets() {Thread.sleep(2000L);//延迟返回数组。asList(new Tweet("RestTemplate rules", "@user1"), new Tweet("WebClient is better", "@user2"), new Tweet("OK, both are useful", "@user1"));}

3.1。使用创建RestTemplate呼叫慢速服务

现在让我们实现另一个REST端点,它将通过web客户机调用我们的慢速服务。

首先,我们将使用创建RestTemplate:

@GetMapping("/ Tweet - BLOCKING ") public List getweetsblocking () {log.info("开始阻塞控制器!");final String uri = getSlowServiceUri();RestTemplate RestTemplate = new RestTemplate();ResponseEntity> response = restTemplate。交易所(uri, HttpMethod。GET, null, new ParameterizedTypeReference>(){});List result = response.getBody();结果。forEach (tweet - > log.info (tweet.toString ()));log.info(“退出阻塞控制器!”);返回结果; }

当我们调用这个端点时,由于的同步性质创建RestTemplate时,代码将阻塞,以等待慢速服务的响应。只有当收到响应时,该方法中的其余代码才会被执行。在日志中,我们将看到:

开始阻塞控制器!推特(文本=创建RestTemplate规则,(电子邮件保护)Tweet(text=WebClient更好,(电子邮件保护)推特(文字=OK,两者都很有用,(电子邮件保护))退出阻塞控制器!

3.2。使用WebClient呼叫慢速服务

其次,让我们使用WebClient呼叫慢速服务:

@GetMapping(value = "/tweets-non-blocking", produces = mediattype . text_event_stream_value) public Flux getweetsnonblocking () {log.info("启动非阻塞控制器!");WebClient.create() .get() .uri(getSlowServiceUri()) .retrieve() .bodyToFlux(Tweet.class);tweetFlux。订阅(tweet - > log.info (tweet.toString ()));log.info(“退出阻塞控制器!”);返回tweetFlux;}

在这种情况下,WebClient返回一个通量发布者和方法执行完成。一旦结果可用,发布者将开始向其订阅者发送tweet。注意,一个客户机(在本例中是一个web浏览器)调用它/ tweets-non-blocking端点也将被订阅到返回的通量对象。

让我们观察这次的日志:

非阻塞控制器开始!退出阻塞控制器!推特(文本=创建RestTemplate规则,(电子邮件保护)Tweet(text=WebClient更好,(电子邮件保护)推特(文字=OK,两者都很有用,(电子邮件保护))

注意,此端点方法在接收响应之前完成。

4.结论

在本文中,我们探索了在Spring中使用web客户机的两种不同方式。

创建RestTemplate使用Java Servlet API,因此是同步和阻塞的。相反,WebClient是异步的,并且在等待响应返回时不会阻塞执行线程。只有当响应就绪时,才会产生通知。

创建RestTemplate仍然会被使用。在某些情况下,非阻塞方法比阻塞方法使用更少的系统资源。因此,在这些情况下,WebClient是一个更好的选择。

本文中提到的所有代码片段都可以找到在GitHub

春天底

通过。开始使用Spring 5和Spring Boot 2学习的春天课程:

> >这门课程
休息下

通过。开始使用Spring 5和Spring Boot 2学习的春天课程:

>>查看课程
6评论
最古老的
最新的
内联反馈
查看所有评论
本文评论关闭!