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。这三个框架各自的定位,以及功能的演进过程值得我们深入进行分析。

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

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

相关文章

计算机英文教材太难啃?Higress 和通义千问帮你!

作者&#xff1a;张添翼&#xff08;澄潭&#xff09; 计算机相关英文教材的中译本质量堪忧&#xff0c;对于计算机专业的学生来说&#xff0c;应该深有体会。因为大部分教材的译者本人可能未必完全吃透书中技术内容&#xff0c;又或者是领域技术大拿&#xff0c;但并不擅长英…

数据结构的归并排序(c语言版)

一.归并排序的基本概念 1.基本概念 归并排序是一种高效的排序算法,它采用了分治的思想。它的基本过程如下: 将待排序的数组分割成两个子数组,直到子数组只有一个元素为止。然后将这些子数组两两归并,得到有序的子数组。不断重复第二步,直到最终得到有序的整个数组。 2.核心…

LabVIEW2017破解安装教程

LabVIEW2017破解安装教程&#xff1a; 1、新版LabVIEW2017分为32位和64位两个平台&#xff0c;多种语言版本(需要LabVIEW2017中文版的朋友请选择WinChn版本)&#xff0c;大家选择自行选择符合系统的版本下载并解压 2、本次安装以Win 7 64位系统为例&#xff0c;运行“2017LV-64…

龙蜥社区 5 月度运营大事件回顾

各位龙蜥社区的朋友们&#xff0c;你们好&#xff01; 龙蜥社区 5 月运营月报如期而至&#xff01;本次从特别图送、龙蜥生态、龙蜥活动、龙蜥 SIG 月度动态、精彩内容推荐等几方面总结、回顾了 5 月发生的重要事件。

设计模式之过滤器模式FilterPattern(十)

一、过滤器模式 过滤器模式&#xff08;Filter Pattern&#xff09;或标准模式&#xff08;Criteria Pattern&#xff09;是一种设计模式&#xff0c;这种模式允许开发人员使用不同的标准来过滤一组对象&#xff0c;通过逻辑运算以解耦的方式把它们连接起来。这种类型的设计模…

【长亭雷池WAF——“动态防护”功能深度体验】

前言&#xff1a; 在当今的网络安全环境中&#xff0c;Web应用防火墙&#xff08;WAF&#xff09;扮演着至关重要的角色。它们不仅能够防御常见的Web攻击&#xff0c;如SQL注入、跨站脚本攻击&#xff08;XSS&#xff09;等&#xff0c;还能够应对日益复杂的网络威胁。 长亭…

如何通过 6 种简单方法将照片从华为转移到 PC?

华为作为全球领先的智能手机供应商之一&#xff0c;最近推出了其自主研发的操作系统——HarmonyOS 2.0&#xff0c;旨在为智能手机、平板电脑和智能手表等设备提供更流畅的用户体验。随着Mate 40/P40等系列手机计划升级到HarmonyOS 2.0&#xff0c;用户可能需要将手机中的文件备…

CAM350如何快速删除Gerber文件上的东西?

文章目录 CAM350如何快速删除Gerber文件上的东西?CAM350如何快速保存已经修改的Gerber文件? CAM350如何快速删除Gerber文件上的东西? CAM如何导入Gerber文件见此篇 今天遇上了一个删除Gerber文件上部分字母的任务&#xff0c;CAM350只能一点点删除线的操作把我手指头差点按…

订单排队与链动模式塑造社交电商新格局

在数字化浪潮中&#xff0c;社交电商凭借其独特的魅力与潜力&#xff0c;正逐渐崭露头角。本文将解读一种融合了订单排队与链动模式的创新商业模式。这一模式旨在通过提高消费者复购率&#xff0c;优化销售流程&#xff0c;从而推动销售增长&#xff0c;塑造社交电商新生态。 …

Mybatis03-ResultMap及分页

1、属性名和字段名不一致问题 1.问题 数据库中的字段 新建一个项目Mybatis-04&#xff0c;拷贝之前&#xff0c;测试实体类字段不一致的情况 public class User {private int id;private String name;private String password; }select * from mybatis.user where id #{id} …

2024年宜昌中级工程师职称如何申报呢?

今年宜昌中级职称如何报名&#xff1f;怎么申报&#xff1f;申报时间是什么时候呢&#xff1f;报名条件是什么呢&#xff1f; 一、2024年宜昌中级职称申报条件&#xff1a;1.社保条件&#xff1a;在宜昌本地注册登记6个月以上民营企业&#xff0c;专业技术岗位从事工程技术工作…

苍穹外卖笔记-02-借助小乌龟创建gitee仓库,apifox代替YApi,Swagger

TOC 1 借助小乌龟创建gitee苍穹外卖仓库 这里建议看视频bilibili比特鹏哥视频 使用软件 git TortoiseGit https://git-scm.com/downloads https://tortoisegit.org/ 使用代码托管平台gitee&#xff0c;git的使用和gitee的账号创建需要查询其他资料 在一个从未克隆仓库的…

3389远程桌面,如何进行3389远程桌面的连接操作

随着信息技术的快速发展&#xff0c;远程桌面连接技术逐渐成为企业、教育以及个人用户进行远程办公、技术支持以及协作交流的重要工具。其中&#xff0c;3389远程桌面因其稳定性和易用性而备受青睐。本文将从专业角度出发&#xff0c;为您详细介绍如何进行3389远程桌面的连接操…

大模型产品的选择:独特优势与个人倾向

层出不穷的大模型产品&#xff0c;你怎么选&#xff1f; 随着近日腾讯元宝APP的正式上线&#xff0c;国内大模型产品又添一员。关于接连出现的“全能“大模型AIGC产品&#xff0c;你都用过哪些呢&#xff1f;不妨来分享一下你的使用体验吧&#xff01;在这些大模型产品中&…

【React篇 】React项目中常用的工具库

我们可以从项目初始化、开发、构建、检查及发布的顺序总结react项目开发常用的工具库。 首先是初始化。 初始化工程项目一般用官方维护的 create-react-app&#xff0c;这个工具使用起来简单便捷&#xff0c;但 create-react-app 的配置隐藏比较深&#xff0c;修改配置时搭配…

LC 26删除有序数组中的重复项

去重题&#xff0c;双指针&#xff0c;&#xff0c;因为题干说原地删除&#xff0c;且nums其余元素不重要。一个cur记录当前不重复的数应该插在第几位了&#xff0c;for循环里的i相当于是第二个指针&#xff08;右指针&#xff09;&#xff0c;遍历数组来找不重复的元素 class …

数据结构:模拟队列

数据结构&#xff1a;模拟队列 题目描述参考代码 题目描述 输入样例 10 push 6 empty query pop empty push 3 push 4 pop query push 6输出样例 NO 6 YES 4参考代码 #include <iostream>using namespace std;const int N 100010;int q[N], hh, tt;int m, x; string …

C++STL---list知识汇总

前言 学习完list&#xff0c;我们会对STL中的迭代器有进一步的认识。list底层有很多经典的东西&#xff0c;尤其是他的迭代器。而list的结构是一个带头双向循环链表。 list没有reserve和resize&#xff0c;因为它底层不是连续的空间&#xff0c;它是用时随时申请&#xff0c;…

windows 系统中部署 windows_exporter

从 github 中下载安装包到本地路径&#xff1a; Releases prometheus-community/windows_exporter (github.com) 后台运行方式windows_exporter&#xff0c;进入命令提示符执行以下命令&#xff1a; > powershell -Command "Start-Process D:\windows_exporter\wind…

快排与归并的算法(非递归版)

一.快排 1.递归法(方法多样) 1>hoare版 注&#xff1a;该方法小编已经在上篇博客中介绍过了&#xff0c;就不在这里过多赘述了&#xff0c;如果有兴趣的小伙伴可以看看小编的上篇博客哦 2>挖坑法 1&#xff09;方法介绍&#xff1a;定义最左边的数据为key&#xff0…