RabbitMQ最全教程-Part1(基础使用)

一、消息队列基本概念

消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构

1、消息队列的特点

可靠性

消息持久化:消息可以被持久化存储,即使消费者暂时不可用,消息也不会丢失。
确认机制:消费者成功处理消息后可以发送确认,确保消息被正确处理。如果处理失败,消息可以被重新发送或回滚。 

负载均衡

多消费者:多个消费者可以竞争消费同一个队列中的消息,实现负载均衡。
高并发:通过增加消费者数量,可以提高系统的处理能力和吞吐量。 

扩展性

水平扩展:可以通过增加更多的生产者和消费者来扩展系统的处理能力。
垂直扩展:可以通过增加服务器资源来提升单个节点的处理能力。

消息排序

顺序消息:某些消息队列支持消息的有序性,确保消息按照发送的顺序被消费。
优先级:可以设置消息的优先级,确保高优先级的消息优先被处理。

2、消息队列的通讯模式

点对点通讯模式

在这种模式下,消息生产者发送的消息会被存储在一个特定的消息队列中,然后由一个或多个消息消费者从该队列中接收消息

发布订阅模式

Pub/Sub 模式允许消息的发送者(发布者)和接收者(订阅者)之间松散耦合,使得多个订阅者可以同时接收相同的消息,消息生产者发布消息到指定Topic,由订阅这个Topic的消费者进行消费

两种模式的比较

请求/回复(Request/Reply)模式

客户端发送请求消息,并等待服务端的回复。服务端将回复消息发送到一个临时队列中,客户端从该队列中获取回复。

延迟消息模式

消息被存储在延时队列中,直到达到指定的时间点才被发送。

广播模式

消息可以被发送到多个队列或主题,每个队列或主题的消费者都会收到消息。

死信队列模式

无法被正常处理的消息会被转移到一个专门的死信队列中。可以对死信队列中的消息进行单独处理,如重试、记录日志等。

3、为什么要使用消息队列

这里列举几种常见应用场景

1)异步处理

举个例子,当用户下单后,将会面临一系列服务调用的流程,比如库存检查、支付处理等,但是这些后续的服务调用都是后台默默做,并不直接影响用户下单这个行为,所以我们可以将这些服务调用变成异步处理,处理完了有结果通知反馈一下就行。

这个异步处理我们可以借助MQ,具体做法:订单系统将订单信息发送到消息队列,后台系统监听到MQ有任务通知,则执行异步处理订单,如库存检查、支付处理、物流安排等。

2)流量削峰

就像用户投递快递,高峰到40W每秒,但是我们的后续处理业务每秒只能20W,还剩下20W在MQ进行堆积,这就是MQ很重要的流量削峰的能力,将用户的洪峰流量,让后台慢慢来处理,MQ承担一个缓冲的作用

比如可以这样做,用户的请求,服务器收到之后,首先写入消息队列进行排队等候真正的服务被执行,但是当加入消息队列长度超过最大值,则直接抛弃用户请求或跳转到错误页面.(这里可以做熔断降级)

3)系统解耦

我们可以看到,如果没加MQ,则一系列调用都是一条完整的同步调用链,某一个服务执行的失败会影响前后的服务。

但是我们通过MQ,可以将后续多个服务单独执行,互不影响,如果有依赖关系,某一个服务执行失败了,我们可以进行一些补偿、回滚机制等

4)实时通知

对于需要实时更新的数据,生产者将更新后的数据发布到Topic上,只要订阅了这个Topic的服务都能够收到这个实时更新的推送,进而做一些实时性的后续处理。

4、消息队列有什么缺点

最直观的就是增加了系统的复杂性,引入了第三方中间件

还有就是增加了网络开销,因为消息的传递是会消耗网络带宽资源的,并且也会带来一定的网络延迟

还有系统可用性降低,因为当MQ宕机了,那么我们有些依赖于MQ进行通信的两两服务之间就失联了

还有一个数据一致性问题,如下图所示,系统需要保证快递投递,扣减系统费,通知等之间的数据一致性,如果系统短信通知,快递通知执行成功,扣减系统费执行失败时,就会出现数据不一致问题

5、各类消息队列的比较

特性ActiveMQRabbitMQKafkaRocketMQ
生产者-消费者模式支持支持支持支持
发布-订阅模式支持支持支持支持
REQUEST-REPLY模式支持支持-支持
API完备性低(静态配置)
多语言支持支持,JAVA优先语言无关支持,JAVA优先支持
单机呑吐量万级万级十万级单机万级
消息延迟毫秒级微秒级毫秒级毫秒级
可用性高(主从)高(主从)很高(分布式)非常高(分布式)
消息丢失-理论上不会丢失理论上不会丢失
消息重复-可控制理论上会有重复允许重复
文档的完备性
提供快速入门
首次部署难度-

注: - 表示尚未查找到准确数据

二、RabbitMQ的基本使用

1、RabbitMQ的一些基本概念、名词解释

Publisher

        消息生产者,就是投递消息的程序

        发布者 (或称为生产者) 负责生产消息并将其投递到指定的交换器上。

Message

        消息由消息头和消息体组成,消息头用于存储与消息相关的元数据:如目标交换器的名字 (exchange_name 指明消息发给哪一个交换器)路由键 (RountingKey)和其他可选配置 (properties) 信息。消息体为实际需要传递的数据。

Exchange

        交换器负责接收来自生产者的消息,并将消息路由到一个或者多个队列中,如果路由不到,则返回给生产者或者直接丢弃,这取决于交换器的 mandatory 属性:

        当 mandatory 为 true 时:如果交换器无法根据自身类型和路由键找到一个符合条件的队列,则会将该消息返回给生产者;
        当 mandatory 为 false 时:如果交换器无法根据自身类型和路由键找到一个符合条件的队列,则会直接丢弃该消息。

BindingKey

        交换器与队列通过 BindingKey 建立绑定关系。  (理解为@RequesMapping,定义了路由跳转

Routingkey

        基于交换器类型的规则相匹配时,消息被路由到对应的队列中

        生产者将消息发给交换器的时候,一般会指定一个 RountingKey,用来指定这个消息的路由规则,当 RountingKey 与 BindingKey相匹配时,消息被路由到对应的队列中。 

        (理解为写的/order/findById   定义了url

Queue

        消息队列载体,每个消息都会被投入到一个或多个队列。

        用于存储路由过来的消息,多个消费者可以订阅同一个消息队列,此时队列会将收到的消息将以轮询的方式分发给所有消费者,即每条消息只会发送给一个消费者,不会出现一条消息被多个消费者重复消费的情况。

Consumer

消息消费者,就是接受消息的程序

        消费者订阅感兴趣的队列,并负责消费存储在队列中的消息。为了保证消息能够从队列可靠地到达消费者,RabbitMQ 提供了消息确认机制 (messageacknowledgement),并通过 autoAck 参数来进行控制

        当 autoAck 为 true 时:此时消息发送出去 (写入TCP套接字) 后就认为消费成功,而不管消费者是否真正消费到这些消息。当 TCP 连接或 channel 因意外而关闭,或者消费者在消费过程之中意外宕机时,对应的消息就丢失。因此这种模式可以提高吞吐量,但会存在数据丢失的风险。
        当 autoAck 为 false 时:需要用户在数据处理完成后进行手动确认,只有用户手动确认完成后,RabbitMQ 才认为这条消息已经被成功处理,这可以保证数据的可靠性投递,但会降低系统的吞吐量。

Connection

        用于传递消息的 TCP 连接。

Channel

     消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。

     RabbitMQ 采用类似 NIO (非阻塞式 IO ) 的设计,通过 Channel 来复用 TCP 连接,并确保每个 Channel的隔离性,就像是拥有独立的 Connection 连接。当数据流量不是很大时,采用连接复用技术可以避免创建过多的 TCP 连接而导致昂贵的性能开销。

Virtual Host

    虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离

    RabbitMQ 通过虚拟主机来实现逻辑分组和资源隔离,一个虚拟主机就是一个小型的 RabbitMQ服务器,拥有独立的队列、交换器和绑定关系。用户可以按照不同业务场景建立不同的虚拟主机,虚拟主机之间是完全独立的,你无法将 vhost1 上的交换器与vhost2 上的队列进行绑定,这可以极大的保证业务之间的隔离性和数据安全,默认的虚拟主机名为 / 。

Broker

        简单来说就是消息队列服务器实体。就是指部署MQ的服务器实体

2、docker安装RabbitMQ

拉取RabbitMQ的镜像

docker pull rabbitmq:management

运行RabbitMQ

docker run -d -p 5672:5672 -p 15672:15672 --name rabbitmq rabbitmq:management

访问管理界面

输入  账号:guest 密码:guest

如果访问不了,可以尝试把linux的防火墙关闭试试

3、交换机类型

Direct exchange(直连交换器)

直连交换机是一种带路由功能的交换机,一个队列会和一个交换机绑定(通过binding_key,一个队列与交换机可以有多条binding_key绑定),当消息被发送的时候,需要指定一个routing_key,这个消息被送达交换机的时候,交换机就会拿着routing_key与binding_key相匹配,只要匹配上的都进行发送到相应的queue

        当生产者(P)发送消息时 Rotuing key=booking 时,这时候将消息传送给 Exchange,Exchange 获取到生产者发送过来消息后,会根据自身的规则进行与匹配相应的 Queue,这时发现 Queue1 和 Queue2 都符合,就会将消息传送给这两个队列。

        如果我们以 Rotuing key=create 和 Rotuing key=confirm 发送消息时,这时消息只会被推送到 Queue2 队列中,其他 Routing Key 的消息将会被丢弃。

Fanout exchange(扇形交换器)

扇型交换机(fanout exchange)将消息路由给绑定到它身上的所有队列,而不理会绑定的路由键。如果 N 个队列绑定到某个扇型交换机上,当有消息发送给此扇型交换机时,交换机会将消息的拷贝分别发送给这所有的 N 个队列。扇型用来交换机处理消息的广播路由(broadcast routing)。

Topic exchange(主题交换器)

直接交换机只能做到routingkey的精确匹配,扇形交换机只能广播到所有queue,那有没有比较折中一点的,可以进行过滤匹配的交换机?主题交换机就是做这个事情的。

对于bindingkey,写匹配的条件:

        可以存在两种特殊字符 “*” 与“#”,用于做模糊匹配,其中 “*” 用于匹配一个单词,“#”用于匹配多个单词(可以是零个)

对于routingkey,写实际路由:

        routing key 为一个句点号 “.” 分隔的字符串(我们将被句点号 “. ” 分隔开的每一段独立的字符串称为一个单词),如“stock.usd.nyse”、“nyse.vmw”、“quick.orange.rabbit”

当生产者发送消息 Routing Key=F.C.E 的时候,这时候只满足 Queue1,所以会被路由到 Queue 中,如果 Routing Key=A.C.E 这时候会被同是路由到 Queue1 和 Queue2 中,如果 Routing Key=A.F.B 时,这里只会发送一条消息到 Queue2 中。

主题交换机拥有非常广泛的用户案例。无论何时,当一个问题涉及到那些想要有针对性的选择需要接收消息的 多消费者 / 多应用(multiple consumers/applications) 的时候,主题交换机都可以被列入考虑范围。

三、SpringBoot整合RabbitMQ

参考文章

SpringBoot快速整合RabbitMQ实现MQ最基本操作_mq基本操作-CSDN博客

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

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

相关文章

英伟达 GPU 架构:演进与模型推理速度的深度关联

英伟达的 GPU 架构演进之路充满了创新与突破。 ©作者|Zane 来源|神州问学 一、 英伟达GPU的架构演进之路 1999 年,英伟达发布 Geforce256 图形处理芯片,首次提出 GPU 概念。早期的架构如 G80 或 GeForce 8800 GTX,包含 8 个 TPC&#…

Yolo V4详解

Yolo V4(You Only Look Once version 4)是一种先进的目标检测系统,于2020年推出。作为Yolo系列算法的最新版本,Yolo V4继承了其前代版本的优点,并在此基础上进行了多项改进,使得其性能得到了显著提升。本文…

实体类中为什么要实现serializable接口

最近见到好多项目中写的代码,在实体类中实现了Serializable接口。说实话:这个在以前学习的时候,貌似学过,但是一直没有用过,所以看着一脸懵逼,但是别人总不可能随便写的吧.....所以就去查了一下这个接口。 …

D55【python 接口自动化学习】- python基础之模块与标准库

day55 练习:实现求导 学习日期:20241101 学习目标:模块与标准库 -- 70 小试牛刀:如何使用Python为函数求导? 学习笔记: 需求分析 使用第三方模块实现函数求导 编写程序并测试 # 求导 from sympy import…

推荐一款功能强大的AI实时变声器:FliFlik Voice Changer

FliFlik VoiCE Changer是一款专注于声音变换与音频处理的创新软件,旨在满足从日常娱乐、游戏直播到播客制作、专业音频编辑的多种应用场景需求。无论是想在游戏中变换声音逗乐队友,还是在播客中塑造个性化的音效,这款软件都能提供灵活而强大的…

Spring Boot技术栈:打造大学城水电管理系统

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统,它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等,非常…

2024 IC行业还能不能入了?

打个有趣的比方,18年以前入行IC的,就业前就知道或者就业后才知道,是去吃席只不过是“农村酒席”,但不至于吃坏肚子。对于这种阵仗,不是每个人都愿意去的,即便是在西电这样的院校,当年也有一些同…

基于双向长短期记忆网络(BiLSTM)的时间序列数据预测,15个输入1个输出,可以更改数据集,MATLAB代码

1. 数据收集与预处理 数据清洗:处理缺失值、异常值等。特征工程:提取有助于预测的特征。数据标准化:将时间序列数据标准化,使其具有零均值和单位方差,有助于模型训练。滑动窗口划分:将时间序列数据划分为多…

基于Python可视化的热门微博数据分析系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于pythondjangovueMySQL的热…

推荐一款非常好用的3d设计软件:LuBan 3D

LuBan 3D是一款非常好用的3d设计软件,这款软件提供独特的3D的模型以及设计的理念,还可以自动为用户处理像三角形OBJ,PLY等网格模型。 基本简介 LuBan 3D是一款非常小巧但是功能十分强大的生成式设计软件。这款软件对于设计师和制作们来说非常…

Comfyui-Flux写实人像摄影风格探索

在一些小伙伴的建议下,我最近开始着手整理ComfyUI的相关内容。其实之前就一直在关注这个工具,但由于工作繁忙,一直没能抽出时间去总结。 与SD webui不同的是,comfyui有着极高的自由度和灵活性,支持高度的定制化和工作流复用&#…

qt QPicture详解

1、概述 QPicture类是Qt框架中的一个重要图形类,它主要用于记录和回放QPainter的绘图指令。这个类能够跨平台、无分辨率依赖地绘制图形,非常适合用于实现打印预览和图像操作等场景。QPicture可以将绘图操作序列化为一种独立于平台的格式,保存…

Axure使用动态面板制作新闻栏目高级交互

亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢! 课程主题:使用动态面板制作新闻栏目 主要内容:动态面板State切换、控制;动态面板滚动设置;设置选中 应用场景&#xff1a…

Jupyter lab 打开时默认使用 Notebook 而不是浏览器

Jupyter lab 打开时默认使用 Notebook 而不是浏览器 正文 正文 今天遇到了一个特别有意思的事情,这里我们以 Windows \textrm{Windows} Windows 系统举例。 我们知道通常我们需要使用如下代码在 Terminal \textrm{Terminal} Terminal 中打开 Jupyter lab \textr…

h5小游戏5--杀死国王(附源码)

源代码如下 1.游戏基本操作 用空格键攻击,kill the king。 css样式源码 charset "UTF-8";font-face {font-family: "AddLGBitmap09";src: url("https://assets.codepen.io/217233/AddLGBitmap09.woff2") format("woff2"…

HtmlAgilityPack 操作详解

目录 1.安装 HtmlAgilityPack 2. 示例 HTML 3. 使用 HtmlAgilityPack 进行 HTML 解析与操作 4. 代码详解 1.加载html文档 2.选择元素 3. 提取属性 4.修改属性 5.常用的几种获取元素的 XPath 写法 HtmlAgilityPack: 轻量且高效,适合进行常规的 H…

图形学常识 | RVT和图像处理

目录 Runtime virtual texture 实时虚拟纹理RVT RVT应用1: 引擎中开启Virtual Texture support vLevel floor[F d(uv)/dx, d(uv)/dy) Random(-0.25,0.25)] RVT的应用2 svt和rvt的区别 双线性过滤和三线性过滤的区别 UE的PixelNormalWS节点 数字图像处理 …

操作符详解

操作符也被叫做&#xff1a;运算符。 操作符的分类 算术操作符&#xff1a; 、- 、* 、/ 、%赋值操作符&#xff1a; 、 、 - 、 * 、 / 、% 、<< 、>> 、& 、| 、^移位操作符&#xff1a;<< >>位操作符&#xff1a;& | ^ ~单目操作符&#…

7、lvm逻辑卷和磁盘配额

lvm逻辑卷概念 lvm基本概念 Lvm 是 Logical Volume Manager 的简称&#xff1a;逻辑卷管理Linux系统下管理硬盘分区的一种机制。lvm适合于管理大存储设备。用户可以动态的对硬盘进行扩容&#xff08;缩容&#xff09;。我们只关心使用层面&#xff0c;对于物理底层&#xff0…

WebGPU跨平台应用开发

对于 Web 开发人员来说&#xff0c;WebGPU 是一个 Web 图形 API&#xff0c;可提供对 GPU 的统一和快速访问。WebGPU 公开了现代硬件功能&#xff0c;并允许在 GPU 上进行渲染和计算操作&#xff0c;类似于 Direct3D 12、Metal 和 Vulkan。 虽然这是真的&#xff0c;但这个故事…