Spring家族中的消息通信解决方案

相信大家对消息通信架构以及各种消息中间件应该都不陌生。在分布式系统的设计和开发过程中,消息通信是用于实现系统解耦、提高扩展性的一大技术体系。而业界关于如何实现消息通信系统也有很多解决方案和对应的开发框架。不知道你有没有发现,在我们每天都在使用到Spring框架中,实际上也包含了一套完整而强大的消息通信机制,被广泛的应用在Spring家族的各个框架中,你可能在不经意中已经在使用这套机制了。今天的内容将围绕这点展开讨论,让你在应用这些框架时知其然更知其所以然。

在Spring家族中,与消息通信机制相关的框架有三个,分别是Spring Messaging、Spring Integration和Spring Cloud Steam。事实上,Spring Cloud中的Spring Cloud Stream是基于Spring Integration实现了消息发布和消费机制并提供了一层封装,很多关于消息发布和消费的概念和实现方法本质上都是依赖于Spring Integration。而在Spring Integration的背后,则依赖于Spring Messaging组件来实现消息处理机制的基础设施。这三个框架之间的依赖关系如下图所示。


接下来的内容,我们先来对位于底层的Spring Messaging和Spring Integration框架做一些展开,方便你在使用Spring Cloud Stream时对其背后的实现原理有更好的理解。

Spring Messaging

Spring Messaging是Spring基础框架中的一个底层模块,用于提供统一的消息编程模型。例如,消息这个数据单元在Spring Messaging中统一定义Message接口,包括一个消息头Header和一个消息体Payload。

public interface Message<T> {

T getPayload();

MessageHeaders getHeaders();

}

而消息通道MessageChannel的定义也比较简单。

public interface MessageChannel {

long INDEFINITE_TIMEOUT = -1;

default boolean send(Message<?> message) {

return send(message, INDEFINITE_TIMEOUT);

}

boolean send(Message<?> message, long timeout);

}

可以看到,我们可以调用MessageChannel的send方法将消息发送至该消息通道中。

消息通道的概念比较抽象,可以简单把它理解为是对队列的一种抽象。通道的名称对应的就是队列的名称,但是作为一种抽象和封装,各个消息通信系统所特有的队列概念并不会直接暴露在业务代码中,而是通过通道来对队列进行配置。下图展示了这层抽象关系。


Spring Messaging把通道抽象成两种基本表现形式,即支持轮询的PollableChannel和实现发布-订阅模式的SubscribableChannel,这两个通道都继承自具有消息发送功能的MessageChannel。

public interface PollableChannel extends MessageChannel {

    Message<?> receive();

    Message<?> receive(long timeout);

}

public interface SubscribableChannel extends MessageChannel {

    boolean subscribe(MessageHandler handler);

    boolean unsubscribe(MessageHandler handler);

}

我们注意到对于PollableChannel而言才有receive的概念,代表这是通过轮询操作主动获取消息的过程。而SubscribableChannel则是通过注册回调函数MessageHandler来实现事件响应。MessageHandler接口定义如下。

public interface MessageHandler {

void handleMessage(Message<?> message) throws MessagingException;

}

通过MessageHandler,我们就可以实现对消息的异步消费。

Spring Integration

Spring Integration是对Spring Messaging的扩展。在Spring Messaging的基础上,Spring Integration还实现了其他几种有用的通道。


这里列举了支持阻塞式队列的RendezvousChannel,该通道与带缓存的QueueChannel都属于点对点通道,但只有在前一个消息被消费之后才能发送下一个消息。PriorityChannel即优先级队列。而DirectChannel是Spring Integration的默认通道,该通道的消息发送和接收过程处于同一线程中。另外还有ExecutorChannel,使用基于多线程的TaskExecutor来异步消费通道中的消息。

Spring Integration的设计目的是为了系统集成,因此内部提供了大量的集成化端点方便应用程序直接使用。当各个异构系统之间进行集成时,如何屏蔽各种技术体系所带来的差异性,Spring Integration为我们提供了即插即用的解决方案。Spring Integration提供的常见集成端点包括HTTP、JDBC、JMS、AMQP、JPA、Mail、MongoDB、Redis等。

Spring Cloud Stream

Spring Cloud Stream是Spring Integration的一种增强,同时与Spring Boot体系进行了融合,也是Spring Cloud家族中专门用来实现微服务环境下消息通信的核心框架。我们先来看一下Spring Cloud Stream中与消息通信相关的内容。

Spring Cloud Stream中的通道

结合前面关于Spring Messaging和Spring Integration中各种概念的描述,我们就不难理解Spring Cloud Stream中关于Source和Sink的定义。Source和Sink都是接口,其中Source接口的定义是这样的。

public interface Source {

String OUTPUT = "output";

@Output(Source.OUTPUT)

MessageChannel output();

}

注意到这里通过Spring Messaging提供的MessageChannel来发送消息,而MessageChannel类来自于Spring Messaging组件。我们在MessageChannel上添加了一个@Output注解,该注解定义了一个输出通道。

类似的,Sink接口定义如下所示。

public interface Sink{

String INPUT = "input";

@Input(Source.INPUT)

SubscribableChannel input();

}

同样,这里通过Spring Messaging中的SubscribableChannel来实现消息接收,而@Input注解定义了一个输入通道。

注意到@Input和@Output注解使用通道名称作为参数,如果没有名称,会使用带注解的方法名字作为参数,也就是默认情况下分别使用“input”和“output”作为通道名称。从这个角度讲,一个Spring Cloud Stream应用程序中的Input和Output通道数量和名称都是可以任意设置的,我们只需要在这些通道的定义上添加@Input和@Output注解即可,这里也给出相应的示例代码。

public interface CustomChannels{

    @Output

    MessageChannel output1();

    @Input

    SubscribableChannel input1();

    

@Input

    SubscribableChannel input2();

}

可以看到,我们在这里定义了一个CustomChannels接口并声明了一个Output通道和两个Input通道,说明使用该通道的服务会从外部的两个通道中获取消息并向外部的一个通道发送消息。注意到上述接口同时使用到了Spring Messaging中的SubscribableChannel和MessageChannel。Spring Cloud Stream对Spring Messaging和Spring Integration提供了原生支持,我们可以直接使用这两个框架所提供的API直接操作消息发布和接收的过程。但在多数场景下,我们不需要依赖这种方式就能完成常见的开发需求。

Spring Cloud Stream整体架构

介绍完Spring Cloud Stream所提供的通道之后,我们来进一步分析它的整体架构。Spring Cloud Stream对整个消息发布和消费过程做了高度抽象,并提供了一系列核心组件。区别于直接使用RabbitMQ、Kafka等消息中间件,Spring Cloud Stream为开发人员提供了一套统一的API。相当于Spring Cloud Stream在消息生产者和消费者之间添加了一种桥梁机制,这种桥梁机制屏蔽了各种消息中间件之间的差异。


在上图中,我们不难看出Spring Cloud Stream具备四个核心组件,分别是Binder、Channel、Source和Sink,其中Binder和Channel成对出现,而Source和Sink分别面向消息的发布者和消费者。我们已经理解了Source、Sink和Channel的概念,这里重点对Binder进行展开。

Spring Cloud Stream中最重要的概念就是Binder。所谓Binder,顾名思义就是一种黏合剂,将业务服务与消息通信系统黏合在一起。通过Binder,我们可以很方便的连接消息中间件,可以动态的改变消息的目标地址、发送方式而不需要了解其背后的各种消息中间件在实现上的差异。到目前为止,Spring Cloud Stream通过Binder组件分别完成了对RabbitMQ以及Kafka的集成,我们可以基于Spring Cloud Stream所提供的统一的API来使用这两款消息中间件,而不需要具体处理它们在消息发布和消费上的差异。这点显著提高了广大开发人员的开发效率。

总结

我们知道软件设计和实现过程都应该采用分层的思想,而Spring框架针对消息通信的解决方案也采用了同样的设计思想。我们发现在Spring中,用于实现消息通信的组件和框架并不是只有一个,而是有三个。从提供消息、通道等基础概念的Spring Messaging开始,到用于构建系统集成总线的Spring Integration,最后才是具备平台型消息通信能力的Spring Cloud Stream。这三个框架各自的定位,以及功能的演进过程值得我们深入进行分析。

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

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

相关文章

小米路由器如何设置去广告功能,如何设置小米路由器的自定义Hosts(小米路由器如何去除小米广告、去除小米电视盒子开屏广告、视频广告)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 实现方案 📒📝 操作步骤📝 注意事项⚓️ 相关链接 ⚓️📖 介绍 📖 小米设备的广告一直是用户头疼的问题,无论是开屏广告、应用内广告还是系统广告,都影响了用户体验。本文将详细介绍如何通过小米路由器实现去除广告…

升级你的提问技巧:ChatGPT-4o时代,如何让对话更智能?

最近&#xff0c;我一直在尝试使用升级版的ChatGPT&#xff0c;也就是GPT-4o&#xff0c;它带来了许多令人兴奋的新功能。要充分利用这个新工具&#xff0c;我们得在提问方式上做些小小的调整。下面&#xff0c;我会从简单到复杂&#xff0c;一一介绍这些调整。 提高提示词的具…

日、周、月度累计发电量、上网电量数据统计平台开发实施案例

一、项目背景及需求 项目需求方为江苏国信集团关联单位&#xff1a;华靖光伏、新能昊扬&#xff0c;项目地点在江苏泰州、江苏扬州&#xff0c;对应分布式光伏发电数采项目。 项目背景&#xff1a;光伏发电并网项目发电量数据采集与开发统计。 需求&#xff1a;对光伏电表数…

STC8增强型单片机进阶开发--OLED显示器(SPI)

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目…

新手快速上手IDEA【常用快捷键】

目录 一、常用二、进阶&#xff08;提高编码速度&#xff09;三、其他四、查找、替换与关闭最后 一、常用 说明快捷键复制代码ctrl c粘贴ctrl v剪切ctrl x撤销ctrl z反撤销ctrl shift z保存-save allctrl s全选-select allctrl a 二、进阶&#xff08;提高编码速度&a…

深入理解可燃气体报警器检验标准:守护工业安全新举措

在工业生产领域&#xff0c;可燃气体报警器扮演着至关重要的角色。它能在气体浓度达到危险水平之前发出警报&#xff0c;为工作人员争取宝贵的逃生时间。 为了确保可燃气体报警器的准确性和可靠性&#xff0c;我们需要遵循一系列严格的检验标准。 在这篇文章中&#xff0c;佰…

【wiki知识库】05.分类管理模块--后端SpringBoot模块

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 一、&#x1f525;今日目标 二、☀SpringBoot代码修改 1.使用逆向工程生成Category表结构 2. 新增CategoryQueryParam 3.新增CategorySaveParam 4.新增CategotyQueryVo 三、&#x1f916;新增分类管理的相关接口…

MySQL—多表查询—多表关系介绍

一、引言 提到查询&#xff0c;我们想到之前学习的单表查询&#xff08;DQL语句&#xff09;。而这一章节部分的博客我们将要去学习和了解多表查询。 对于多表查询&#xff0c;主要从以下7个方面进行学习。 &#xff08;1&#xff09;第一部分&#xff1a;介绍 1、多表关系 2、…

记录layui-table中操作列的宽度随着权限变化而变化

最近做一个项目&#xff0c;某个页面因为角色不同&#xff0c;所以显示的的按钮有所不同。 管理员权限 普通人员权限 layui引入的table宽度是写死的&#xff0c;不能随着自动变化&#xff0c;查了一些资料&#xff0c;让写入css的方法 .layui-table th, .layui-table td { whi…

智能楼宇安防3D数据可视化平台满足日益增长的安防需求

在当今社会&#xff0c;安全是每个人和企业最为关心的问题。为满足日益增长的安防需求&#xff0c;3D可视化公司深圳华锐视点隆重推出安防平台3D可视化管理系统&#xff0c;以先进的三维技术为您的安全保驾护航。 安防平台3D可视化管理系统通过创新的三维可视化技术&#xff0c…

优化你的WordPress网站:内链建设与Link Whisper Pro插件的利用

文章目录 内链的重要性WordPress SEO插件&#xff1a;Link Whisper Pro主要功能使用指南下载与安装 结语 在数字营销和网站管理领域&#xff0c;SEO内部优化是提升网站排名、增加流量和提高用户参与度的核心策略。在众多SEO技巧中&#xff0c;内链建设是构建良好网站结构和提升…

Glide支持通过url加载本地图标

序言 glide可以在load的时候传入一个资源id来加载本地图标&#xff0c;但是在开发过程中。还得区分数据类型来分别处理。这样的使用成本比较大。希望通过自定义ModelLoader实现通过自定义的url来加载Drawab。降低使用成本 实现 一共四个类 类名作用GlideIcon通过自定义url的…

轻松搭建AI应用的三个大模型技术路线

时下聊起AI&#xff0c;想必最热的就是使用AI的应用&#xff08;chatGPT&#xff0c;文心一言等&#xff09;来提升自己工作的效率&#xff0c;比如破局俱乐部&#xff0c;洋哥带领星球2万多人开启大航海&#xff0c;教人使用这一波新起的应用进行赚钱与赋能。 在我的视角来看…

PS系统教程11

HUD拾色器 作用&#xff1a;它可以帮助使用者更加高效地选择和使用颜色&#xff0c;从而提高工作效率和设计质量。 先确定色相值改变饱和度改变亮度使用HUD拾色器选中画笔工具画笔模式-正常shiftAlt右键 色相轮 上下移动从黑到白亮度变化左右移动从浅到深饱和度的变化选中颜…

探索 Adobe Illustrator 2023 (AI 2023) for Mac/Win——创意设计的强大工具

Adobe Illustrator 2023 (AI 2023) for Mac/Win 是一款在设计领域备受推崇的专业矢量图形编辑软件软件&#xff0c;为设计师们提供了无尽的创意可能性。 它具有强大而精确的绘图功能&#xff0c;让用户能够轻松绘制出各种复杂的图形、线条和形状。无论是简洁的图标设计还是精美…

不服就干!FEAST微生物溯源:一场微生物“寻根究底”的浪漫之旅

微生物一直处于不断变化的状态&#xff0c;估计不同源微生物群落&#xff08;source,“源”&#xff09;对特定微生物群落&#xff08;sink,“汇”&#xff09;的贡献或混合比例被称为微生物溯源&#xff08;MST&#xff09;问题。了解样本中这些生物体来自何处以及如何形成群落…

机器学习之数学基础(六)~时间复杂度和空间复杂度

目录 算法背景 background 1. 时间复杂度 Time Complexity 1.1 时间复杂度分类 1.1.1 O(1) 常数阶 1.1.2 O(n) 线性阶 1.1.3 O(n^2) 平方阶 1.1.4 O(logn) 对数阶 1.1.5 O(nlogn) 线性对数阶 1.1.6 O(2^n) 指数阶 1.1.7 O(n!) 阶乘阶 1.1.8 时间复杂度分类 1.2 时…

记录Nuxt 3 官网项目的一次部署

本来以为就是一次简单的部署&#xff0c;之前也是部署过几次nuxt项目了&#xff0c;所以&#xff0c;并没有要记录的想法。但是过程出现了很多问题&#xff0c;最后考虑还是写下来吧。留个记录&#xff08;完整的配置部署过程&#xff09; 这里我将要说明两种部署方式以供选择&…

electron-Vue: Module parse failed: Unexpected character ‘ ‘

​ electron-Vue项目中&#xff0c;我自己写了一个node的C扩展&#xff08;xx.node&#xff09;&#xff0c;然后在.vue文件里import它&#xff0c;然后运行npm run electron:serve&#xff0c;报错如下: ​​ electron-Vue打包默认使用webpack&#xff0c;默认情况下webpack没…

Vue2.0项目搭建流程(一步一步教你如何初始化一个前端项目)

文章目录 1.环境准备2.项目初始化3.删除不必要的初始化文件 1.环境准备 1.winr在cmd终端界面输入node -v&#xff0c;检测node环境是否安装成功 2.cmd终端界面输入vue -V&#xff0c;检测前端脚手架vue/cli是否安装成功 没有显示则终端输入以下指令 //以下内容三选一 cnpm …