定义

队列 Queue 是一种先进先出的数据结构,所以消费消息时也是按照顺序来消费的

消息队列看作是一个存放消息的容器,需要使用消息的时候,直接从容器中取出消息供自己使用即可

参与消息传递的双方称为 生产者 和 消费者

  • 生产者负责发送消息
  • 消费者负责处理消息

操作系统中的进程通信的一种很重要的方式就是消息队列

当前我们说的是:指的是各个服务以及系统内部各个组件/模块之前的通信,属于一种 中间件

中间件就是一类为应用软件服务的软件,应用软件是为用户服务的,用户不会接触或者使用到中间件
常见的中间件有

  • 消息队列
  • RPC 框架
  • 分布式组件
  • HTTP 服务器
  • 任务调度框架
  • 配置中心
  • 数据库层的分库分表工具
  • 数据迁移工具

消息队列可以降低系统耦合性、实现任务异步、有效地进行流量削峰,是分布式和微服务系统中重要的组件之一

作用

三点好处:

  • 异步处理:将用户请求中包含的耗时操作,通过消息队列实现异步处理,将对应的消息发送到消息队列之后就立即返回结果,减少响应时间,提高用户体验。随后,系统再对消息进行消费

  • 削峰/限流:先将短时间高并发产生的事务消息存储在消息队列中,然后后端服务再慢慢根据自己的能力去消费这些消息,这样就避免直接把后端服务打垮掉

  • 降低系统耦合性:生产者(客户端)发送消息到消息队列中去,消费者(服务端)处理消息,需要消费的系统直接去消息队列取消息进行消费即可而不需要和其他系统有耦合,这显然也提高了系统的扩展性

  • 其他的如下

    • 实现分布式事务
    • 顺序保证
    • 数据流处理

异步处理

异步处理:将用户请求中包含的耗时操作,通过消息队列实现异步处理,将对应的消息发送到消息队列之后就立即返回结果,减少响应时间,提高用户体验。随后,系统再对消息进行消费

因为用户请求数据写入消息队列之后就立即返回给用户了,但是请求数据在后续的业务校验、写数据库等操作中可能失败。因此,使用消息队列进行异步处理之后需要适当修改业务流程进行配合

比如用户在提交订单之后,

  • 订单数据写入消息队列,不能立即返回用户订单提交成功
  • 需要在消息队列的订单消费者进程真正处理完该订单之后,甚至出库后,再通过电子邮件或短信通知用户订单成功,以免交易纠纷
  • 这就类似我们平时手机订火车票和电影票。

削峰/限流

削峰/限流:先将短时间高并发产生的事务消息存储在消息队列中,然后后端服务再慢慢根据自己的能力去消费这些消息,这样就避免直接把后端服务打垮掉

削峰(Peak Shaving)实现方案:

  • 异步缓冲机制生产者突发高并发请求写入消息队列,避免直接冲击下游服务,消费者按恒定速率从队列拉取消息,将“脉冲流量”转为“稳定流”
  • 队列容量控制:设置队列最大长度(如 RabbitMQ 的 x-max-length),超出时拒绝新消息或转入死信队列

限流分为:

  • 生产者限流
  • 消费者限流

降低系统耦合性

降低系统耦合性:生产者(客户端)发送消息到消息队列中去,消费者(服务端)处理消息,需要消费的系统直接去消息队列取消息进行消费即可而不需要和其他系统有耦合,这显然也提高了系统的扩展性

消息队列使用发布-订阅模式工作,消息发送者(生产者)发布消息,一个或多个消息接受者(消费者)订阅消息

消息发送者(生产者)和消息接受者(消费者)之间没有直接耦合

对新增业务,只要对该类消息感兴趣,即可订阅该消息对原有系统和业务没有任何影响,从而实现网站业务的可扩展性设计

消息队列不只能利用发布-订阅模式工作,只是在解耦这个特定业务环境下是使用发布-订阅模式的

除了发布-订阅模式,还有点对点订阅模式(一个消息只有一个消费者),我们比较常用的是发布-订阅模式。

这两种消息模型是 JMS 提供的,AMQP 协议还提供了另外 5 种消息模型

实现分布式事务

事务允许事件流应用将消费,处理,生产消息整个过程定义为一个原子操作

核心实现原理:事务消息机制

  • 半消息(Prepared Message)‌生产者发送消息到消息队列,但该消息‌对消费者不可见‌(处于"待确认"状态),避免消费者过早处理未完成的事务
  • 执行本地事务‌生产者执行本地业务操作(如订单创建),并根据结果决定提交或回滚事务消息
    • 提交‌:消息变为可见状态,供消费者消费。‌
    • 回滚‌:消息直接被丢弃
  • 事务状态回查‌:若生产者未明确提交/回滚(如宕机),消息队列会主动回查生产者本地事务状态,确保事务完整性

典型流程(以订单+积分场景为例)

1. 创建订单数据
2. 写入任务表
3. 定时扫描任务
4. MQ持久化半消息
5. 通知订单服务
6. 执行本地事务
7a. 提交事务
7b. 回滚事务
8. 消息可见
9. 检查幂等性
10. 不存在则处理
11. 通知订单服务
12. 删除任务表数据
订单服务
订单数据库
tb_task 任务表
发送半消息到MQ
MQ Server
用户服务消费消息
Redis/DB查重
增加积分

顺序保证

在很多应用场景中,处理数据的顺序至关重要。

消息队列保证数据按照特定的顺序被处理,适用于那些对数据顺序有严格要求的场景。

大部分消息队列,例如 RocketMQ、RabbitMQ、Pulsar、Kafka,都支持顺序消息。

消息队列主要通过‌队列机制、分区策略和消费端控制‌实现消息顺序保证,核心是确保同一业务标识的消息在同一个处理通道内串行化

顺序性保证本质是‌牺牲并发度换取业务一致性‌。主流方案均采用 ‌“分区有序”‌(同一 Key 同队列同线程),避免全局有序的性能瓶颈

延时/定时处理

消息发送后不会立即被消费,而是指定一个时间,到时间后再消费

大部分消息队列,例如 RocketMQ、RabbitMQ、Pulsar,都支持定时/延时消息。

即时通讯

消息队列实现即时通讯(IM)主要通过‌异步消息传递协议‌和‌实时推送机制‌实现,核心依赖长连接、消息路由和状态管理

MQTT(消息队列遥测传输协议)是一种轻量级的通讯协议,采用发布/订阅模式,非常适合于物联网(IoT)等需要在低带宽、高延迟或不可靠网络环境下工作的应用

支持即时消息传递,即使在网络条件较差的情况下也能保持通信的稳定性

RabbitMQ 内置了 MQTT 插件用于实现 MQTT 功能(默认不启用,需要手动开

典型工作流程(以私聊为例)

用户A Broker 用户B DB 发布消息到Topic: chat/A_B 若B在线,立即推送 若B离线,持久化消息 上线后拉取未读消息 推送离线消息 发送ACK确认 删除已送达消息 用户A Broker 用户B DB

数据流处理

针对分布式系统产生的海量数据流,如业务日志、监控数据、用户行为等,消息队列可以实时或批量收集这些数据,并将其导入到大数据处理引擎中,实现高效的数据流管理和处理

问题注意

系统可用性降低:在加入 MQ 之前,你不用考虑消息丢失或者说 MQ 挂掉等等的情况,但是,引入 MQ 之后你就需要去考虑

系统复杂性提高: 加入 MQ 之后,需要保证消息没有被重复消费、处理消息丢失的情况、保证消息传递的顺序性等等问题

一致性问题消息队列可以实现异步,消息队列带来的异步确实可以提高系统响应速度。但是,万一消息的真正消费者并没有正确消费消息就会导致数据不一致的情况

JMS 规范

基本概念

JMS(JAVA Message Service,java 消息服务)是 Java 的消息服务JMS 的客户端之间可以通过 JMS 服务进行异步的消息传输

JMS 是一个消息服务的标准或者说是规范,允许应用程序组件基于 JavaEE 平台创建、发送、接收和读取消息

支持消息类型

JMS 定义了五种不同的消息正文格式以及调用的消息类型,允许发送并接收以一些不同形式的数据:

  • StreamMessage:Java 原始值的数据流
  • MapMessage:一套名称-值对
  • TextMessage:一个字符串对象
  • ObjectMessage:一个序列化的 Java 对象
  • BytesMessage:一个字节的数据流

JMS 两种消息模型

点到点(P2P)模型

使用队列(Queue)作为消息通信载体;满足生产者与消费者模式,一条消息只能被一个消费者使用未被消费的消息在队列中保留直到被消费或超时
在这里插入图片描述

发布/订阅(Pub/Sub)模型

发布订阅模型(Pub/Sub) 使用主题(Topic)作为消息通信载体,类似于广播模式;发布者发布一条消息,该消息通过主题传递给所有的订阅者
在这里插入图片描述

AMQP协议

AMQP,即 Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准 高级消息队列协议(二进制应用层协议),是应用层协议的一个开放标准,为面向消息的中间件设计兼容 JMS

基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件同产品,不同的开发语言等条件的限制
RabbitMQ 就是基于 AMQP 协议实现的

JMS vs AMQP

AMQP 为消息定义了线路层(wire-level protocol)的协议JMS 定义的是 API 规范

在 Java 体系中,多个 client 均可以通过 JMS 进行交互,不需要应用修改代码,但是其对跨平台的支持较差。
而 AMQP 天然具有跨平台、跨语言特性

JMS 支持 TextMessage、MapMessage 等复杂的消息类型;而 AMQP 仅支持 byte[] 消息类型(复杂的类型可序列化后发送)

由于 Exchange 提供的路由算法,AMQP 可以提供多样化的路由方式来传递消息到消息队列,而 JMS 仅支持 队列 和 主题/订阅 方式两种

对比方向JMSAMQP
定义Java API协议
跨语言
跨平台
支持消息模型提供两种消息模型:①Peer-2-Peer;②Pub/sub提供了五种消息模型:①direct exchange;②fanout exchange;③topic change;④headers exchange;⑤system exchange。本质来讲,后四种和 JMS 的 pub/sub 模型没有太大差别,仅是在路由机制上做了更详细的划分;
支持消息类型支持多种消息类型byte[](二进制)

RPC 和消息队列的区别

RPC 和消息队列本质上是网络通讯的两种不同的实现机制,两者的用途不同

用途来看:

  • RPC 主要用来解决两个服务的远程通信问题不需要了解底层网络的通信机制。通过 RPC 可以帮助我们调用远程计算机上某个服务的方法,这个过程就像调用本地方法一样简单。
  • 消息队列主要用来降低系统耦合性、实现任务异步、有效地进行流量削峰。

通信方式来看:

  • RPC 是双向直接网络通讯
  • 消息队列是单向引入中间载体的网络通讯。

从架构上来看:

  • 消息队列需要把消息存储起来
  • RPC 不需要存储消息,因为前面也说了 RPC 是双向直接网络通讯。

从请求处理的时效性来看:

  • 通过 RPC 发出的调用一般会立即被处理
  • 存放在消息队列中的消息并不一定会立即被处理。

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

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

相关文章

算法-动态规划-钢条切割问题

钢条切割问题是一个经典的动态规划问题,旨在通过切割钢条获得最大收益。以下是详细解释和解决方案: 问题描述 给定长度为 n 的钢条和价格表 p,其中 p[i] 表示长度为 i 的钢条的价格(i 1, 2, ..., n)。目标&#xff…

DeepSeek:中国AI开源先锋的技术突破与行业革新

在人工智能技术迅猛发展的浪潮中,DeepSeek(深度求索)作为中国AI领域的新锐力量,凭借其创新的技术路线和开源策略,正在全球AI舞台上崭露头角。这家由知名量化投资机构幻方量化支持的AI公司,自2023年7月成立以…

cmake:动态链接库(dll)的调用

如题,动态链接库的调用和静态链接库有所不同,现将步骤整理如下。 动态链接库文件 正常情况下,编译的动态链接库有五个生成文件和对应的头文件,在调用中,使用dll文件,lib文件 和头文件。编译生成动态库的步骤和配置见C++:动态链接库的编写,__declspec 用法详解-CSDN博…

SAP调用api

之前是把SAP程序封装成api,然后又接到了需求是sap调用其他api,直接上代码吧 FUNCTION ZRFC_PP_016. *"---------------------------------------------------------------------- *"*"Local interface: *" IMPORTING *" …

Idea/Pycharm用法总结

在目录里展开当前文件

Python打卡训练营Day56

DAY 56 时序数据的检验 知识点回顾: 假设检验基础知识 原假设与备择假设P值、统计量、显著水平、置信区间 白噪声 白噪声的定义自相关性检验:ACF检验和Ljung-Box 检验偏自相关性检验:PACF检验 平稳性 平稳性的定义单位根检验 季节性检验 ACF检…

[GESP202312 五级] 烹饪问题

题目描述 有 N N N 种食材,编号从 0 0 0 至 N − 1 N-1 N−1,其中第 i i i 种食材的美味度为 a i a_i ai​。 不同食材之间的组合可能产生奇妙的化学反应。具体来说,如果两种食材的美味度分别为 x x x 和 y y y ,那么它们…

JSON Mock 工具:从接口模拟到前端联调(二)

JSON Mock 工具:模拟JSON API 接口(一)-CSDN博客 上一篇学习到,JSON Mock 工具,是用于模拟返回 JSON 数据的 API 接口,解决后端接口未就绪时前端无法开发测试的问题,实现 “无后端依赖” 的前端…

质量小议55 - 搜索引擎与AI

先有搜索引擎(谷歌、百度),后有AI(chatGPT,deepSeek,文心一主,CSDN助手) 慢慢的百度用的少了,更多的是直接向AI工具提问 虽然搜索引擎也有了AI版的结果,而且是置顶的,但更多的时间在用A…

Life:Internship in OnSea Day 0

Prolog This will be a new serial Blog to record my internship life in OnSea(I like this straightly translation of hell divers). As usual,这些 Blogs 主要还是给 自分自身 看的,以便日后考古自己的 career。 既然已经这个系列归类到了 Life 类…

ChangeNotifierProvider 本质上也是 Widget

场景 void main() {runApp(MyApp()); }class MyApp extends StatelessWidget {const MyApp({super.key});overrideWidget build(BuildContext context) {return ChangeNotifierProvider(create: (context) > MyAppState(),child: MaterialApp(title: Namer App,theme: Them…

【软考高级系统架构论文】论负载均衡技术在Web系统中的应用

论文真题 负载均衡技术是提升Web系统性能的重要方法。利用负载均衡技术,可将负载(工作任务)进行平衡、分摊到多个操作单元上执行,从而协同完成工作任务,达到提升Web系统性能的目的。 请围绕“负载均衡技术在Web系统中的应用”论题&#xff…

pyqt5工具-串口调试工具

目录 功能界面代码功能 串口设置:支持选择串口、波特率、数据位、停止位和校验位 串口操作:扫描串口、打开 / 关闭串口连接 数据收发: 支持文本和 Hex 模式显示与发送 可设置自动添加换行符 接收区自动滚动 支持中文显示 辅助功能:清空接收区、状态栏显示连接状态 多串口管…

Mybatis-Plus支持多种数据库

使用Mybatis-Plus进行数据库的访问,但是由于不同的数据库有不同的方言,所以需要进行适配。 有2种实现方式: databaseId方式Mapper Location方式 指定databaseId方式 通过databaseId指定所使用的数据库,选择同步的SQL。 Mappe…

【系统分析师】2018年真题:综合知识-答案及详解

【第1题】 面向对象分析中,对象是类的实例。对象的构成成分包含了(1),属性和方法(或操作)。 (1)A.标识 B.消息 C.规则 D.结构 【解析】本题考查的是面向对象的基本概念 对象的三要素为:属性…

从Git历史中删除大文件的完整解决方案

从Git历史中删除大文件的完整解决方案 当你意外提交了一个大文件导致无法推送到远程仓库时,可以按照以下步骤彻底从Git历史中删除这个大文件。 情况分析 首先确认你的问题属于以下哪种情况: 大文件在最近一次提交中:相对容易处理大文件在…

[xiaozhi-esp32] 应用层(9种state) | 音频编解码层 | 双循环架构

第三章:应用层 在第一章:开发板抽象层中,我们实现了硬件交互标准化;在第二章:通信协议层中,我们构建了云端通信桥梁。 现在需要将这些能力有机整合——这便是应用层的使命 应用层的本质 应用层是设备的…

Java 锁升级的过程详解

Java 锁升级的过程详解 Java 虚拟机(JVM)为了提高多线程并发的效率,对内置锁(synchronized 关键字)的实现进行了一系列优化。这些优化体现在锁的升级过程中,即当竞争程度从低到高变化时,锁的状态会从偏向锁逐渐升级为轻量级锁,最终升级为重量级锁。这个过程是不可逆的…

使用vitis tcl脚本构建vitis app工程

一:最近重新学习了zynq系列开发,想着使用tcl创建工程,因此分享一下脚本例子 #!/bin/bashsource /tools/Xilinx/Vitis/2022.2/settings64.sh cd ../../ . ./script/project.sh cd app/script #tcl脚本只能在虚拟机桌面执行 xsct build_vitis…

电脑商城--购物车

加入购物车 1 购物车-创建数据表 1.使用use命令先选中store数据库。 USE store; 2.在store数据库中创建t_cart用户数据表。 CREATE TABLE t_cart (cid INT AUTO_INCREMENT COMMENT 购物车数据id,uid INT NOT NULL COMMENT 用户id,pid INT NOT NULL COMMENT 商品id,price BIG…