响应式编程Spring Reactor探索

news2024/11/25 20:40:09

一,介绍

响应式编程(Reactive Programming),简单来说是一种生产者只负责生成并发出数据/事件,消费者来监听并负责定义如何处理数据/事件的变化传递方式的编程思想。

响应式编程借鉴了Reactor设计模式,我们通常会在高性能NIO网络通信框架中见到Reactor设计模式的身影,用来实现I/O多路复用。

基本思想是将所有要处理的I/O事件注册到一个中心I/O多路复用器上,同时主线程阻塞在多路复用器上,通过轮询或者边缘触发的方式来处理网络I/O事件。当有新的I/O事件到来或准备就绪时,多路复用器返回并将事件分发到对应的处理器中。Reactor设计模式和响应式编程类似,它们都不主动调用某个请求的API,而是通过注册对应接口,实现事件触发执行。

Reactor 诞生在响应式流规范制定之后,从一开始就是严格按照响应式流规范设计并实现了它的 API,因此Spring 选择它作为默认响应式编程框架。

背压处理
背压是所有响应式编程框架所必须要考虑的核心机制,Reactor 框架支持所有常见的背压传播模式,包括以下几种。

纯推模式:订阅者通过 subscription.request(Long.MAX_VALUE) 请求有效无限数量的元素。

纯拉模式:订阅者通过 subscription.request(1) 方法在收到前一个元素后只请求下一个元素。

推-拉混合模式:当订阅者有实时控制需求时,发布者可以适应所提出的数据消费速度。

二,动手实现

1,引入pom

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

2,Controller层创建Mono来接收请求

创建Mono,设置超时时间为60秒,将任务交给service层去处理,请求会在这儿挂着,然后可以继续接收新的请求。service层处理后续业务,处理完成之后,调用monoSink.success方法返回。

如果60秒没有处理完成,就直接完成这个请求,发送超时的返回值。

如果中途执行中出现校验异常之类的,也会直接返回,结束这个请求。

/**
 * 接收请求
 *
 * @param cmd 请求指令
 * @return 结果
 */
@PostMapping(value = "order")
public Mono<OrderResponse> order(@RequestBody OrderCmd cmd, ServerHttpRequest request) {
    return createMono(cmd, request);
}
/**
 * 创建 Mono
 *
 * @param cmd     请求指令
 * @param request 请求
 * @return Mono
 */
public Mono<OrderResponse> createMono(OrderCmd cmd, ServerHttpRequest request) {
    // 生成关联 ID
    String correlationId = genCorrelationId(request.getId());
    // 创建MonoSink, 执行业务逻辑
    return Mono.create((Consumer<MonoSink<OrderResponse>>) monoSink -> orderService.dealRequest(correlationId, cmd, monoSink))
            // 超时时间
            .timeout(Duration.ofSeconds(60))
            //只处理 OrderException,给正常响应包
            .onErrorResume(OrderException.class, e -> Mono.just(orderService.dealException(correlationId, cmd, e)))
            .doOnSuccess(obj -> {
                if (Objects.equals(obj.get("超时返回"), "超时返回")) {
                    exceptionNoticesService.notice(new OrderException("超时返回"));
                }
            });
}

3,service层执行逻辑,并注册dispose事件

可以将MonoSink缓存,后面业务逻辑执行完成之后从缓存中获取MonoSink对象。

// 将对象存储
cacheStore.put(correlationId, monoSink);

// 当完成其操作并关闭时,onDispose方法会被调用,以便释放资源或执行其他必要的清理工作。
monoSink.onDispose(() -> cacheStore.remove(correlationId));

//完成业务逻辑之后,调success方法,返回请求结果

MonoSink<OrderResponse> monoSink = cacheStore.get(correlationId);
monoSink.success(transResponse);

三,小结

Spring Reactor框架是响应式编程的一个很好的实践,能帮助开发者快速完成相关的需求,能很好的实现支持背压处理。

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

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

相关文章

一文搞懂前端跨页面通信的那些方案们

前端开发逃避不开跨页面通信这项工作&#xff0c;跨页面通信&#xff0c;就好比A页面要和B页面说话&#xff0c;可能只是说一句话&#xff0c;不需要回话&#xff0c;可能是要给一些东西&#xff0c;希望得到回复&#xff0c;并频繁进行沟通&#xff0c;接下来我们说说这些跨页…

图搜索算法 - 拓扑排序

相关文章&#xff1a; 数据结构–图的概念 图搜索算法 - 深度优先搜索法&#xff08;DFS&#xff09; 图搜索算法 - 广度优先搜索法&#xff08;BFS&#xff09; 拓扑排序 概念 几乎所有的工程都可分为若干个称作活动的子工程&#xff0c;而这些子工程之间&#xff0c;通常受…

Figma 高效技巧:设计系统中的图标嵌套

Figma 高效技巧&#xff1a;设计系统中的图标嵌套 在设计中&#xff0c;图标起着不可或缺的作用。一套便捷易用的图标嵌套方法可以有效提高设计效率。 分享一下我在图标嵌套上走过的弯路和经验教训。我的图标嵌套可以分三个阶段&#xff1a; 第一阶段&#xff1a;建立图标库 一…

洛谷官方提单——【入门4】数组——python

洛谷官方提单——【入门4】数组 小鱼比可爱题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示代码 小鱼的数字游戏题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示数据规模与约定 代码 【深基5.例3】冰雹猜想题目描述输入格式输出格式样例 #1样例输入 …

24深圳杯ABCD成品论文47页+各小问代码+图表

A题多个火箭残骸的准确定位&#xff1a; A题已经更新完22页完整版论文&#xff0b;高清无水印照片&#xff0b;Python&#xff08;MATLAB&#xff09;代码简单麦麦https://www.jdmm.cc/file/2710544/ 问题1&#xff1a;单个残骸的音爆位置确定 建模思路&#xff1a; 1. 声波传…

Codeforces Round 942 (Div.1) (Div. 2) 2A~2D

2A.Contest Proposal&#xff08;枚举&#xff09; 题意&#xff1a; 一个竞赛包含 n n n个问题&#xff0c;第 i i i个问题的难度预计最多为 b i b_i bi​。现在已经有 n n n个问题提案&#xff0c;第 i i i个问题的难度为 a i a_i ai​。最初&#xff0c; a 1 , a 2 , … ,…

为什么现在越来越多的人会选择陪诊

现在越来越多的人选择陪诊的原因有多方面。 首先&#xff0c;随着人口老龄化、医疗资源分配不均等问题的日益突出&#xff0c;许多老年人和病患在就医过程中面临诸多困难&#xff0c;如挂号、排队、取药等繁琐的手续和流程。陪诊服务能够为他们提供极大的便利&#xff0c;帮助…

spring模块(六)spring监听器(2)@EventListener

一、介绍 监听器的简化写法 二、原理 三、使用 Slf4j Component public class MyTask {EventListenerpublic void onApplicationEvent(ApplicationEvent event) {if (event instanceof ContextRefreshedEvent) {log.info("监听到 ContextRefreshedEvent...");}if…

[图解]DDD架构好简单我学会了-学会也没啥用

1 00:00:03,720 --> 00:00:05,920 内部共有&#xff0c;首先是内部的 2 00:00:08,150 --> 00:00:09,220 所以不能说什么 3 00:00:09,630 --> 00:00:10,730 不能跟外部连在一起 4 00:00:10,740 --> 00:00:15,280 比如说&#xff0c;功能架构&#xff0c;可以吗 …

使用Linux命令时,前面加sudo和不加有什么区别?

在使用cmake命令编译时&#xff0c;前面加上sudo和不加主要有以下区别&#xff1a; 权限&#xff1a; 使用sudo&#xff1a;当您在命令前加上sudo时&#xff0c;表示您以超级用户的权限执行该命令。这通常用于需要访问受限制的系统文件或执行需要更高权限的操作。不使用sudo&am…

Swift 字符串和字符

字符串和字符 一、字符串字面量1、多行字符串字面量2、字符串字面量的特殊字符3、扩展字符串分隔符 二、初始化空字符串三、字符串可变性四、字符串是值类型五、使用字符六、连接字符串和字符七、字符串插值八、Unicode1、Unicode 标量2、可扩展的字形群集 九、计算字符数量十、…

『ZJUBCA Collaboration』WTF Academy 赞助支持

非常荣幸宣布&#xff0c;浙江大学区块链协会收到WTF Academy的赞助与支持&#xff0c;未来将共同开展更多深度合作。 WTF Academy是开发者的Web3开源大学&#xff0c;旨在通过开源教育让100,000名开发者进入到Web3。截止目前&#xff0c;WTF开源教程在GitHub收获超15,000 ⭐&a…

五一假期Llama 3之魔改不完全攻略(Part 2)

2024年4月18日&#xff0c;Meta AI 正式宣布推出 Llama 3&#xff0c;这标志着开源大型语言模型&#xff08;LLM&#xff09;领域的又一重大进步。如同一颗重磅炸弹&#xff0c; Llama 3 以其卓越的性能和广泛的应用前景&#xff0c;预示着 AI 技术的新时代。 目前开源的是Lla…

H62410A dcdc 24V30V36V48V60V72V100V降压12V/5V1A 恒压电源芯片IC

DCDC 24V-30V-36V-48V-60V-72V-100V降压至12V/5V 1A恒压电源芯片IC的工作原理主要基于开关调节和PWM&#xff08;脉冲宽度调制&#xff09;控制。 首先&#xff0c;芯片内部通常包含一个高速开关&#xff0c;通常是一个MOSFET&#xff08;金属氧化物半导体场效应晶体管&#x…

MySQL·内置函数

目录 函数 日期函数 案例1&#xff1a;创建一张表&#xff0c;记录生日 案例2&#xff1a;创建一个留言表 案例3&#xff1a;请查询在2分钟内发布的帖子 字符串函数 案例1&#xff1a; 获取emp表的ename列的字符集 案例2&#xff1a;要求显示exam_result表中的信息&am…

XShell 无法连上 VirtualBox的系统问题排查

之前一直都是可以正常使用的&#xff0c;过了一段时间之后&#xff0c;我发现无法使用XShell连接我之前安装的Centos 系统了。 我在centos中ping windows的IP地址&#xff0c;是可以 ping 通的&#xff0c; 百度也可以 ping 通&#xff0c;但是在 windows 中 ping centos的IP地…

湘潭大学数据库作业题完整答案

作业一&#xff1a; 考虑如下所示的关系数据库。这些关系上适当的主码是什么&#xff1f; 职工&#xff08;姓名&#xff0c;街道&#xff0c;城市&#xff09; 工作&#xff08;姓名&#xff0c;公司名&#xff0c;工资&#xff09; 公司&#xff08;公司名&#xff0c;城市&a…

【时序大模型总结】学习记录(1)

1.TimeGPT-1 思路&#xff1a;在来自不同领域的大量数据上训练模型&#xff0c;然后对未见过的数据产生零样本的推断。 作者对TimeGPT进行了超过1000亿个数据点的训练&#xff0c;这些数据点都来自开源的时间序列数据。该数据集涵盖了广泛的领域&#xff0c;从金融、经济和天气…

卧式负压排渣放水器为煤矿添彩

拥有自己的一片小天地&#xff0c;让每个角落都充满生活的色彩。快来找到心仪的产品&#xff0c;为煤矿添彩&#xff01; 一、排渣放水器的概述&#xff1a; 负压自动排渣放水器的型号为FYPZ&#xff0c;FY指负压放水器中的负压&#xff0c;PZ指自动排渣&#xff0c;FYPZ的全称…

初学C++——C++基础、变量、字面量、常量、数据类型、类型转换、变量命名规则、开发环境配置

文章目录 简介C 语言的特性C 开发环境配置C 变量&#xff0c;字面量和常量C 变量变量命名规则 C 字面量C 常量 C 数据类型C 基本数据类型派生数据类型 C 类型转换隐式类型转换C 显式转换 简介 C 是一种静态类型的&#xff0c;自由形式的&#xff08;通常&#xff09;编译的&…