响应式编程Spring Reactor探索

一,介绍

响应式编程(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框架是响应式编程的一个很好的实践,能帮助开发者快速完成相关的需求,能很好的实现支持背压处理。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

神器:jQuery一键转换为纯净JavaScript代码

我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版&#xff0c;欢迎购买。点击进入详情 该工具将 jQuery 代码转换为现代、高效的 JavaScript。它允许您用纯 JavaScript 替换 jQuery&#xff0c;同时保持原始代码不变。 虽然 jQuery 一直是 Web 开发中…

防火墙技术基础篇:什么是包过滤技术

什么是防火墙包过滤技术 当数据在网络中传输时&#xff0c;它们被分割成小的单元&#xff0c;称为数据包。防火墙的包过滤是一种基本的网络安全技术&#xff0c;用于检查这些数据包并根据预定义的规则决定是否允许它们通过防火墙。 防火墙包过滤是一种关键的网络安全技术&am…

在下游市场需求带动下 轮胎模具市场规模逐渐扩大

在下游市场需求带动下 轮胎模具市场规模逐渐扩大 轮胎模具是通过硫化、成型等工序生产各种轮胎的一种工具。轮胎模具是生产轮胎的关键设备之一&#xff0c;其性能直接影响到轮胎的耐用性和安全性。根据花纹加工工艺不同&#xff0c;轮胎模具加工工艺可分为精密铸造工艺、数控雕…

炒美股怎么开户?

近年来&#xff0c;随着国内投资者对境外投资需求的不断增长&#xff0c;炒美股逐渐成为许多投资者的选择。然而&#xff0c;随着监管政策的不断完善&#xff0c;传统的互联网券商开户方式已经不再适用。那么&#xff0c;对于想要入场美股市场的投资者来说&#xff0c;该如何开…

实现左上角的固定视口但是网格以图片中心放大缩小

仅仅修改了showbk&#xff08;&#xff09; 函数部分&#xff0c;增加bkv4 直接采样&#xff0c;然后粘贴到左上角&#xff0c;实现多余部分裁剪&#xff0c;形成视口内放大缩小 // 程序&#xff1a;2D RPG 地图编辑器与摄像机追随 // 作者&#xff1a;bilibili 民用级脑的研发…

windows10打印机共享完美解决方案

提到文件共享大家并不陌生,相关的还有打印机共享,这个多见于单位、复印部,在一个区域网里多台电脑共用一台打印机,打印资料非常方便,就包括在家里,我们现在一般都会有多台电脑或设备,通过家庭网络联接,如果共享一台打印机的话也是件便捷的事。 但是随着操作系统的更新…

Win11任务栏通知很不明显的解决方案

Win11流行起来后&#xff0c;不少用户抱怨Win11的任务栏通知闪烁的颜色很不明显&#xff0c;经常微信来消息了看不到。虽然有右下角的微信图标会闪烁&#xff0c;但是提醒舒适度还是觉得不如Win10舒服显眼。 默认的颜色是这样子的&#xff0c;可以看得出Win11的任务栏提醒颜…

QGraphicsItem的prepareGeometryChange 和 update方法区别

prepareGeometryChange 这个函数用于为图形的几何形状变化做准备。在改变一个项目的边界矩形之前调用此函数&#xff0c;以保持 QGraphicsScene 的索引是最新的。如果必要的话&#xff0c;prepareGeometryChange() 会调用 update()。QGraphicsScene认为所有图元的boundingRect…

Python数据分析常用模块的介绍与使用

Python数据分析模块 前言一、Numpy模块Numpy介绍Numpy的使用Numpy生成数组ndarrayarray生成数组arange生成数组random生成数组其他示例 关于randint示例1示例2 关于rand Numpy数组统计方法示例 二、Pandas模块pandas介绍Series示例 DataFrame示例 三、其他模块Matplotlib/Seabo…

Apache Knox 2.0.0使用

目录 介绍 使用 gateway-site.xml users.ldif my_hdfs.xml my_yarn.xml 其它 介绍 The Apache Knox Gateway is a system that provides a single point of authentication and access for Apache Hadoop services in a cluster. The goal is to simplify Hadoop securit…

【Qt】Qt开发中常用命名规范、快捷键和窗口坐标体系详解

Qt是一款强大的跨平台C应用程序开发框架&#xff0c;为了提高代码的可读性和可维护性&#xff0c;遵循一定的命名规范是非常重要的。此外&#xff0c;Qt Creator提供了许多快捷键和便捷功能&#xff0c;能够提高开发效率。本文将介绍Qt开发中常用的命名规范、快捷键以及窗口坐标…

来聊聊Java项目分层规范

写在文章开头 近期和读者交流聊到项目规范&#xff0c;借着这个机会我们不妨聊聊主流Java项目是如何进行分层的。 Hi&#xff0c;我是 sharkChili &#xff0c;是个不断在硬核技术上作死的 java coder &#xff0c;是 CSDN的博客专家 &#xff0c;也是开源项目 Java Guide 的维…

[华为OD]C卷 运输时间 200 动态规划

题目&#xff1a; M辆车需要在一条不能超车的单行道到达终点&#xff0c;起点到终点的距离为N。速度快的车追上前车 后&#xff0c;只能以前车的速度继续行驶&#xff0c;求最后一车辆到达目的地花费的时间。 注意&#xff1a; 每辆车固定间隔1小时出发&#xff0c;比如第…

静态NAT

哈喽&#xff01;各位小伙伴们好久不见&#xff0c;最近由于工作的原因断更了一段时间&#xff0c;不过最近我都会把这些给补上&#xff0c;今天我们来学习一个简单的知识——静态NAT转换。 第一章 什么是NAT技术&#xff1f; 网络地址转换技术NAT&#xff08;Networ…

红帽发布Red Hat Enterprise Linux AI(RHEL AI)

红帽 2024 峰会正在科罗拉多州丹佛市举行…鉴于当前的时代背景&#xff0c;人工智能&#xff08;AI&#xff09;在此次峰会上占据了重要位置&#xff0c;因此红帽公司&#xff08;Red Hat&#xff09;也不甘人后宣布推出 RHEL AI。 红帽公司今天发布了 Red Hat Enterprise Lin…

优化电脑空间清理电脑占用磁盘空间垃圾

1. 清理磁盘 右下角放大镜&#xff0c;搜索 此电脑 点击要清理的磁盘 &#xff0c;比如点击C盘&#xff0c;右键属性&#xff0c;常规选项卡&#xff0c;点击清理磁盘&#xff0c; 和点击清理系统文件 1.1 优化磁盘 右下角放大镜&#xff0c;搜索 此电脑 点击要清理的磁盘 &…

RUST 编程语言使构建更安全的软件变得更加容易。RUST ALL THE THINGS 需要什么?

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

基于Spring Ai 快速创建一个AI会话

文章目录 1、创建SpringBoot项目2、引入依赖3、修改配置文件4、一个简单的会话 前期准备 在OpenAI 注册页面创建帐户并在API 密钥页面生成令牌。 Spring AI 项目定义了一个配置属性&#xff0c;您应该将其设置为从 openai.com 获取的spring.ai.openai.api-key值 代码托管于gite…

sql查询数据语句

select * from 表名 where 列名 某个数据名字 查询某个表名中的某列是否有某个数据

基于卷积神经网络的高光谱图像分类详细教程(含python代码)

目录 一、背景 二、基于卷积神经网络的代码实现 1&#xff09;建立卷积神经网络模型 2&#xff09;训练函数代码 3&#xff09;全图可视化 三、项目代码 一、背景 卷积神经网络&#xff08;Convolutional Neural Networks, CNNs&#xff09;在处理高光谱图像分类任务时&…