Cloud-Platform 学习——Part6 WebClient异步非阻塞请求工具


参考:

  • https://zhuanlan.zhihu.com/p/370935458?utm_id=0 - 知乎专栏
  • 在 SpringBoot 中从 RestTemplate 过渡到 WebClient:详细指南-CSDN博客

多年来,Spring 框架的 RestTemplate 一直是客户端 HTTP 访问的首选解决方案,它提供同步、阻塞 API 来以简单的方式处理 HTTP 请求。
然而,随着对非阻塞、反应式编程以更少的资源处理并发的需求不断增加,特别是在微服务架构中,RestTemplate 已经显示出其局限性。从 Spring Framework 5 开始,RestTemplate 已被标记为已弃用,Spring 团队推荐 WebClient 作为其继任者。

RestTemplate 与 WebClient 区别:

  • RestTemplate
    使用了基于每个请求对应一个线程模型(thread-per-request)的 Java ServletAPl。发送请求时,RestTemplate 为每个事件(HTTP 请求)创建一个新的线程,该线程直到 Web 客户端收到响应之前,都将一直被阻塞下去。而阻塞代码带来的问题则是,每个线程都消耗了一定的内存和 CPU 周期。这些线程将耗尽线程池或占用所有可用内存。由于频繁的 CPU上下文(线程)切换,我们还会遇到性能下降的问题
  • WebClient
    不同于 RestTemplate,WebClient 是异步的,它为每个事件创建类似于“任务“,幕后,Reactive 框架对这些 “任务” 进行排队,并仅在适当的响应可用时执行它们,等待响应的同时不会阻塞正在执行的线程。只有在响应结果准备就绪时,才会发起通知。
    WebClient 是 Spring WebFlux 库的一部分。因此,我们还可以使用流畅的函数式 API 编写客户端代码,并将响应类型(Mono 和 Flux)作为声明来进行组合。

1.引入依赖

<!--WebClient--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

2.使用工具发送请求

@Test
void webclientCreate(){//WebClient webClient = WebClient.builder().baseUrl(BASE_URI).build();WebClient webClient = WebClient.create(BASE_URI);//普通请求Mono<String> mono = webClient.get() //get请求.uri(BASE_URI + "/test/get01") //WebClient.create()不带BASE_URI时就得写上请求头.retrieve() //获取响应体.bodyToMono(String.class); //格式化响应数据//携带请求参数——拼接请求地址栏Mono<String> mono01 = webClient.get().uri(uriBuilder -> uriBuilder.path("/test/get02").queryParam("pageSize",10).queryParam("pageNum",1).build()).retrieve().bodyToMono(String.class);//携带请求参数——放到body中User user = User.builder().id("0000").password("0000").build();Mono<User> mono02 = webClient.post().uri(uriBuilder -> uriBuilder.path("/test/post01").build()).contentType(MediaType.APPLICATION_JSON).body(Mono.just(user),User.class)
//                .header().retrieve().bodyToMono(User.class);}

3.获取结果

    log.info("{}",mono.block());mono.subscribe(result -> System.out.println(result));//subscribe()方法用于订阅结果,一旦可用就会对其进行处理

4.处理错误

RestTemplate 的错误处理通过ErrorHandler接口进行,这需要单独的代码块,而 WebClient 允许直接在操作链中处理特定的 HTTP 状态,从而提供更具可读性和可维护性的方法

WebClient  webClient  = WebClient.create(); 
webClient.get() .uri( "http://example.com/some-error-endpoint" ) .retrieve() .onStatus(HttpStatus::isError, response -> { // 处理错误状态码return Mono.error ( new  CustomException ( "发生自定义错误。" )); }) .bodyToMono(String.class);

5.流数据

WebClient 还支持以数据流的形式检索响应主体,这在处理您不想一次将其全部保存在内存中的大量数据时特别有用。

WebClient  webClient  = WebClient.create(); 
webClient.get() .uri( "http://example.com/stream" ) .accept(MediaType.TEXT_EVENT_STREAM) // 用于服务器发送事件 (SSE).retrieve() .bodyToFlux(String.class) //将响应正文转换为 Flux.subscribe(data -> System.out.println( "Received: " + data));

在此场景中,bodyToFlux用于将响应正文转换为Flux,表示数据流。然后,该subscribe方法用于在每条数据到达时对其进行处理。这与 RestTemplate 形成鲜明对比,后者要求在处理之前将整个响应主体加载到内存中,无论大小如何。

6.重试机制

WebClient  webClient  = WebClient.builder().baseUrl( "http://example.com" ).build(); 
Mono<String> response = webClient.get() .uri( "/retry-endpoint" ) .retrieve() .bodyToMono(String.class) .retryWhen(Retry.backoff( 3 , Duration.ofSeconds( 1 )) //重试次数和退避配置.maxBackoff(Duration.ofSeconds( 10 ))) // 最大退避时间.onErrorResume(e -> Mono.just( "Fallback response" )); // 如果重试都失败则回退response.subscribe(result -> System.out.println(result));

在此示例中,该retryWhen方法用于定义重试策略,指定重试次数和退避配置。如果所有重试都失败,onErrorResume则提供后备机制。

等等…

扩展:FeignClient 与 WebClient

https://springdoc.cn/spring-boot-feignclient-vs-webclient/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/588577.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php的laravel权限问题

1.这是我新建的一个路由&#xff0c;然后就是说每新建一个路由都要给他开个权限&#xff01;&#xff01;&#xff01;&#xff01; 2.这个是组内大佬写的&#xff1a; 我们也可以在里面加&#xff0c;也可以在浏览器的页面手动加&#xff08;对我们新手来说还是浏览器的页面…

matlab导出高清图片,须经修改后放入latex(例如添加文字说明,matlab画图不易操作)

一、背景 我们在写文章时&#xff0c;使用matlab画图后&#xff0c;如果不需要对图片进行额外修改或调整&#xff0c;例如添加文字说明&#xff0c;即可直接从matlab导出eps格式图片&#xff0c;然后插入到latex使用。 通常latex添加图片&#xff0c;是需要eps格式的。 但很…

左耳朵耗子:程序员练级攻略

在一个小公司&#xff0c;天天 CRUD&#xff0c;程序员如何练级&#xff0c;不断提升自己&#xff1f; 在大公司&#xff0c;就是个螺丝钉&#xff0c;天天就是自己那一亩三分地&#xff0c;如何不断提升自己&#xff0c;不被淘汰&#xff1f; 第一步建立自己的学习实验室 在…

微服务实战系列之Dubbo(下)

前言 眼看着2023即将走远&#xff0c;心里想着似乎还有啥&#xff0c;需要再跟各位盆友叨叨。这不说曹操&#xff0c;曹操就来了。趁着上一篇Dubbo博文的余温尚在&#xff0c;博主兴匆匆地“赶制”了Dubbo的下集&#xff0c;以飨读者。 上一篇博主依然从Dubbo的内核出发&#…

UTF-8编码:打破字符编码的国界

UTF-8编码&#xff1a;打破字符编码的国界 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;让我们一同探讨编程世界中一项至关重要的技术——“UTF-…

原型链补充

1.什么是原型对象 函数的独有属性,他用prototype来表示,可以在函数的prototype上挂载一些公用的属性和方法,供实例化对象来访问。 2.__proto__属性 这个属性每一个对象都有,实例化对象就是通过这个属性,来访问原型对象上的属性和方法的。 3.三者之间的关系 1.在构造函数的原型…

PTA——计算火车运行时间

本题要求根据火车的出发时间和达到时间&#xff0c;编写程序计算整个旅途所用的时间。 输入格式&#xff1a; 输入在一行中给出2个4位正整数&#xff0c;其间以空格分隔&#xff0c;分别表示火车的出发时间和到达时间。每个时间的格式为2位小时数&#xff08;00-23&#xff0…

Vagrant使用教程

vmware下载地址&#xff1a;https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html VirtualBox下载地址&#xff1a;https://www.virtualbox.org/wiki/Downloads Vagrant下载地址&#xff1a;https://developer.hashicorp.com/vagrant/install#…

基于智能手机的行人惯性追踪数据集模型与部署

论文总结 这篇《 Smartphone-based Pedestrian Inertial Tracking: Dataset, Model, and Deployment 》论文介绍了一种基于智能手机惯性测量单元&#xff08;IMU&#xff09;的行人追踪和定位系统。主要内容和贡献如下&#xff1a; 数据集和实验设计&#xff1a;作者开发了一…

logback中的logger和root

1. logger和root的区别 在logback中&#xff0c;logger和root logger都是日志记录器&#xff08;logger&#xff09;的实例&#xff0c;用于控制日志的输出级别。它们之间的区别在于它们的作用范围和默认配置。 logger是应用程序中的具体组件或类的日志记录器。每个logger都可…

鸿蒙 DevEco Studio 3.1 入门指南

本文主要记录开发者入门&#xff0c;从软件安装到项目运行&#xff0c;以及后续的学习 1&#xff0c;配置开发环境 1.1 下载安装包 官网下载链接 点击立即下载找到对应版版本 下载完成&#xff0c;按照提示默认安装即可 1.2 下载SDK及工具链 运行已安装的DevEco Studio&…

SPI机制原理+使用

一、概述 SPI全称&#xff08;Service Provider Interface&#xff09;&#xff0c;是JDK内置的一种服务提供发现机制&#xff1b;SPI机制提供了组件发现和注册方式&#xff0c;可以为应用程序提供灵活的插件机制&#xff0c; 主要原理&#xff1a;接口 反射 配置文件。 二、…

Rust学习笔记002: 猜字游戏

version0.1 // 导入标准库中的 io 模块&#xff0c;它包含了输入输出相关的功能 use std::io;// 程序的入口点 fn main() {println!("Guess the number!");println!("Please input your guess.");// 创建一个可变的字符串变量 guess&#xff0c;用于存储用…

【Spring Security】快速入门之案例实操

目录 一、简介 1、什么是安全框架 2、主流的安全框架 3、为什么使用Spring Security 二、引言 1、什么是Spring Security 2、Spring Security工作原理 3、特点 三、快速入门 1、引入依赖 2、配置 3、启动测试 4、配置自定义账号密码 四、Web安全配置类 1.HttpSe…

一步一步写线程之三多线程设计开发

一、多线程开发 多线程开发在实际应用中是非常多的。正如前面分析所说&#xff0c;只要写一个线程&#xff0c;就可以认为是多线程开发。多线程开发没有最优&#xff0c;只有在指定场景下的最合适。没有任何一个模型可以包打所有的场景&#xff0c;所以在网上经常可以看到一些…

智安网络|实现安全与网络功能一体化:SASE的全新安全策略

随着企业信息化和数字化程度的不断提升&#xff0c;网络安全面临着前所未有的挑战。传统的网络安全模式已经无法满足日益复杂的安全需求。在这一背景下&#xff0c;安全访问服务边缘&#xff08;SASE&#xff09;崭露头角&#xff0c;并逐渐成为新一代网络安全架构的关键概念。…

云上安全责任共担模型

对于传统自建物理服务器模式&#xff0c;用户需要承担所有的安全责任&#xff0c;负责从物理基础设施到上层应用的所有层面的安全体系构建。 云服务器的安全责任确实与物理服务器不同&#xff0c;云上的安全性是一种责任共担模式&#xff0c;其中云服务器ECS的安全责任需要你&…

Hive中支持毫秒级别的时间精度

实际上&#xff0c;Hive 在较新的版本中已经支持毫秒级别的时间精度。你可以通过设置 hive.exec.default.serialization.format 和 mapred.output.value.format 属性为 1&#xff0c;启用 Hive 的时间精度为毫秒级。可以使用以下命令进行设置&#xff1a; set hive.exec.defau…

分布式技术之故障恢复技术

文章目录 分布式故障基础知识故障类型故障检测故障恢复 分布式故障检测原理故障恢复策略 分布式故障基础知识 故障类型 在任何一个分布式系统中&#xff0c;故障都是不可避免的。这里的故障&#xff0c;通常包括两类&#xff1a; 一类是物理故障&#xff0c;比如硬盘损坏、断电…

异常检测 | Matlab基于GNN图神经网络的数据异常数据检测

异常检测 | Matlab基于GNN图神经网络的数据异常数据检测 目录 异常检测 | Matlab基于GNN图神经网络的数据异常数据检测效果一览基本介绍模型描述程序设计参考资料 效果一览 基本介绍 Matlab基于GNN图神经网络的数据异常数据检测。其核心思想是学习一个函数映射。本次使用人类活…