RabbitMQ基础知识
1.1 什么是MQ?
消息队列(Message Queue),是基础数据结构中 “先进先出” 的一种数据结构。
一般用来解决应用解耦、异步消息、流量削峰等问题,实现高性能、高可用、可伸缩和最终一致性架构。
RabbitMQ可以理解为一个邮箱,或者一个邮局,或者是一个邮递员,保证 “张三” 的信件最终传递给 “李四”。
RabbitMQ与上述所描述的邮局(邮箱、邮递员)的主要区别在于它不处理纸张,而是接受、存储和转发二进制数据块消息。
1.2.MQ的应用场景
- 跨系统间的调用
比如说发送短息的功能,信息在自己应用中处理完成之后,调用第三方发送短信接口,假如第三方接口有问题或者延迟比较大,就会影响自己接口的响应时间,用户的体验就会很差,并且第三方也是不可控的,这时候就可以把发送短信的操作放到队列中执行,如果第一次发送消息失败,还可以重复执行, 这些操作对用户都是无感知的,避免因为第三方系统出现的问题导致自己系统出现问题 - 系统内的异步调用
比如发送评论后 异步进行更新排行榜的功能
比如批量发送消息的功能,加入给100w用户发送消息,时间肯定会很长,改为异步在后台慢慢消费,用户就会无感知,并且很快的通知发送消息方已经发送完成了 - 消息驱动的场景
比如当满足一个条件以后,触发后面的一系列操作,这个时候用程序实现起来比较麻烦,这个时候使用消息队列来实现就会相当的简单 - 跨语言之间的调用
因为消息队列是和语言无关的,也不是函数之间的调用,而且消息队列也不要求生产端和消费端同时在线,所以很轻松的实现跨语言间的调用
1.3 MQ是怎么实现消息传递的?
- 生产者产生消息并把传输的数据(消息)放在队列中,用队列机制来实现消息传递。
- 消费者可以到指定的队列拉取消息,或者订阅相应的队列,由MQ服务端给其推送消息。
1.4 MQ的几个主要特性
- 解耦:一个业务需要多个模块共同实现,或一条消息有多个系统对应处理,只需要在主业务完成以后,发送一条MQ,其余模块消费MQ消息,即可实现业务,降低模块之间的耦合。
- 异步:主业务执行结束后,从属业务通过MQ异步处理,减少业务的响应时间,提高用户体验。
- 削峰:高并发情况下,业务异步处理,提供高峰期业务处理能力,避免系统瘫痪。
1.5.MQ的缺点
- 系统可用性降低。依赖服务越多,服务越容易挂掉。需要考虑MQ瘫痪的情况。
- 系统的复杂性提高。需要考虑消息丢失、消息重复消费、消息传递的顺序性。
- 业务一致性。主业务和从属业务一致性的处理。
1.6RabbitMQ的相关术语术语
- Producer生产者:用来发送消息到队列
- Consumer消费者:从队列中取出消息消费掉
- Queue存储消息的容器:它就是队列,它就是消息的载体,每个消息都会通过队列让消费者来消费
- Channel消息通道:可以和rabbitmq建立一个链接,一个链接中也可以有多个的通道
- Exchange交换机:决定交换机以什么规则发送到队列中
- Routing Key:路由的关键字,交换机就是通过它来决定发送到哪个队列中,就是通过它来路由的
1.7RabbitMQ的工作模式(5种)
1.7.1简单工作模式

这里不需要交换机,应用场景:1对1的聊天
1.7.2 work工作模式

左边是一个生产者发送消息到队列中,多右边是多个消费者竞争消费消息,在高并发场景下,容易出现同一个消息被多个消费者消费的问题,需要注意(可以在业务上增加唯一的键值来避免)
应用场景:红包
1.7.3 订阅模式,每个队列的消息都是一样的

左边是一个生产者,把消息发送给交换机,交换机分别把消息发送到多个队列中,最后由消费者来消费
1.7.4 路由模式,根据routing key发送到不同的消息队列中(使用的是定向类型的交换机)

左边是一个生产者发送了一条消息,交换机根据发送的路由key,发送到相匹配的队列中,由消费者来消费
应用场景:日志(不同等级的日志有不同的方法,所以会放到不同的队列中,error走上吗的队列,info走下面的队列)
1.7.5 主题模式,根据routing key分类,发送到不同的消息队列中

主题模式使用的topic类型的交换机,和上面的路由模式类似,主要通过通配符和#来判断消息发送到哪个队列中,发送到哪个队列中,是通过和#来通过routing key 来决定的,其中#匹配一个或多个单词,*匹配一个单词
2. go使用RabbitMQ
安装RabbitMQ扩展包
go get github.com/streadway/amqp
首先编写demo,简单模式和工作模式

RabbitMq其本质是tcp链接,并且是基于内部通道进行的通信,所以一个完整的连接分为连接与创建通道两部分。
连接地址的格式是这种形式:
amqp://admin:123456@127.0.0.1:5672/
services创建mq.go,实现封装

生产者流程
在 Golang 中创建 rabbitmq 生产者基本步骤是:
-
连接 Connection
-
创建 Channel
-
创建或连接一个交换器
-
创建或连接一个队列
-
交换器绑定队列
-
投递消息
-
关闭 Channel
-
关闭 Connection
创建连接
// connection
connection, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
创建通道
// channel
channel, err := connection.Channel()
创建交换器
err = channel.ExchangeDeclare("e1", "direct", true, false, false, true, nil)
参数依次说明:
-
name交换机名称 -
kind交换机类型 -
durable持久化标识 -
autoDelete是否自动删除 -
internal是否是内置交换机 -
noWait是否等待服务器确认 -
args其它配置
参数说明要点:
autoDelete :
自动删除功能必须要在交换器曾经绑定过队列或者交换器的情况下,处于不再使用的时候才会自动删除,如果是刚刚创建的尚未绑定队列或者交换器的交换器或者早已创建只是未进行队列或者交换器绑定的交换器是不会自动删除的。
internal :
内置交换器是一种特殊的交换器,这种交换器不能直接接收生产者发送的消息,只能作为类似于队列的方式绑定到另一个交换器,来接收这个交换器中路由的消息,内置交换器同样可以绑定队列和路由消息,只是其接收消息的来源与普通交换器不同。
noWait
当 noWait 为 true 时,声明时无需等待服务器的确认。
该通道可能由于错误而关闭。 添加一个 NotifyClose 侦听器应对任何异常。创建交换器还有一个差不多的方法( ExchangeDeclarePassive ),他主要是假定交换已存在,并尝试连接到不存在的交换将导致 RabbitMQ 引发异常,可用于检测交换器的存在。
创建队列
q, err := channel.QueueDeclare("q1", true, false, false, true, nil)
参数说明:
-
name队列名称 -
durable持久化 -
autoDelete自动删除 -
exclusive排他 -
noWait是否等待服务器确认 -
args Table其它配置
参数说明要点:
exclusive 排他
排他队列只对首次创建它的连接可见,排他队列是基于连接( Connection )可见的,并且该连接内的所有信道( Channel)都可以访问这个排他队列,在这个连接断开之后,该队列自动删除,由此可见这个队列可以说是绑到连接上的,对同一服务器的其他连接不可见。
同一连接中不允许建立同名的排他队列的这种排他优先于持久化,即使设置了队列持久化,在连接断开后,该队列也会自动删除。
非排他队列不依附于连接而存在,同一服务器上的多个连接都可以访问这个队列。
autoDelete 设置是否自动删除。为 true 则设置队列为自动删除。
自动删除的前提是:至少有一个消费者连接到这个队列,之后所有与这个队列连接的消费者都断开时,才会自动删除。
不能把这个参数错误地理解为:“当连接到此队列的所有客户端断开时,这个队列自动删除”,因为生产者客户端创建这个队列,或者没有消费者客户端与这个队列连接时,都不会自动删除这个队列。
创建队列还有一个差不多的方法( QueueDeclarePassive ),他主要是假定队列已存在,并尝试连接到不存在的队列将导致 RabbitMQ 引发异常,可用于检测队列的存在。
绑定交换器和队列
err = channel.QueueBind("q1", "q1Key", "e1", true, nil)
参数解析:
-
name队列名称 -
key BindingKey根据交换机类型来设定 -
exchange交换机名称 -
noWait是否等待服务器确认 -
args Table其它配置
绑定交换器(可选)
err = channel.ExchangeBind("dest", "q1Key", "src", false, nil)
参数解析:
-
destination目的交换器 -
key RoutingKey路由键 -
source源交换器 -
noWait是否等待服务器确认 -
args Table其它参数
生产者发送消息至交换器 source 中,交换器 source 根据路由键找到与其匹配的另一个交换器 destination ,井把消息转发到 destination 中,进而存储在 destination 绑定的队列 queue 中,某种程度上来说 destination 交换器可以看作一个队列。
投递消息
err = channel.Publish("e1", "q1Key", true, false, amqp.Publishing{Timestamp: time.Now(),DeliveryMode: amqp.Persistent, //Msg set as persistentContentType: "text/plain",Body: []byte("Hello Golang and AMQP(Rabbitmq)!"),
})
参数解析:
-
exchange交换器名称 -
key RouterKey路由键 -
mandatory是否为无法路由的消息进行返回处理 -
immediate是否对路由到无消费者队列的消息进行返回处理 RabbitMQ 3.0 废弃 -
msg消息体
参数说明要点:
mandatory
消息发布的时候设置消息的 mandatory 属性用于设置消息在发送到交换器之后无法路由到队列的情况对消息的处理方式,设置为 true 表示将消息返回到生产者,否则直接丢弃消息。
immediate
参数告诉服务器至少将该消息路由到一个队列中,否则将消息返回给生产者。 imrnediate 参数告诉服务器,如果该消息关联的队列上有消费者,则立刻投递:如果所有匹配的队列上都没有消费者,则直接将消息返还给生产者,不用将消息存入队列而等待消费者了。
RabbitMQ 3.0版本开始去掉了对 imrnediate 参数的支持。
其中 amqp.Publishing 的 DeliveryMode 如果设为 amqp.Persistent 则消息会持久化。需要注意的是如果需要消息持久化 Queue 也是需要设定为持久化才有效。
消费者流程
在 Golang 中创建 rabbitmq 消费者基本步骤是:
-
连接 Connection
-
创建 Channel
-
创建或连接一个交换器
-
创建或连接一个队列
-
交换器绑定队列
-
消费消息
-
关闭 Channel
-
关闭 Connection
消费者的步骤和生产者流程基本类似,只是将生产者流程中的投递消息变为消费消息。
相关文章:
RabbitMQ基础知识
1.1 什么是MQ? 消息队列(Message Queue),是基础数据结构中 “先进先出” 的一种数据结构。 一般用来解决应用解耦、异步消息、流量削峰等问题,实现高性能、高可用、可伸缩和最终一致性架构。 RabbitMQ可以理解为一个邮箱&#x…...
基于Python大数据的音乐推荐及数据分析可视化系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏:Java精选实战项目…...
安达发|太阳能设备行业APS计划排程软件能解决哪些问题
在当今快速发展的太阳能设备行业中,高级计划与排程(APS)软件成为了企业优化生产流程、提高生产效率和满足市场需求的关键工具。APS软件通过集成先进的算法和数据分析技术,为企业提供了一个全面的生产计划和排程解决方案。本文将探…...
CaChe的基本原理
目录 一、Cache的定义与结构 二、Cache的工作原理 三、Cache的映射与替换策略 四、Cache的写操作处理 Cache,即高速缓冲存储器,是计算机系统中位于CPU与主存之间的一种高速存储设备。它的主要作用是提高CPU对存储器的访问速度,从而优化系…...
数据结构-栈(理解版)
一、栈的定义 相信大家对于栈或多或少有一些了解,可能大多数人会告诉你栈是一种先进后出的数据结构。这其实说了跟没说一样(❁◡❁)!当然(last in,first out)是栈最有特色的性质。 这里可以给大家一些比较好理解的例…...
NAND Flash虚拟层初始化
在整个NAND Flash初始化过程中,其主要过程由NAND_Init()函数来完成的,因此以下以NAND_Init()函数作为入口,对NAND Flash虚拟层初始化进行全面分析: NAND_Init()NAND_PhyInit()FMT_Init()FMT_FormatNand()LML_Init() NAND_Init()函数首先调用NAND_PhyInit()函数…...
zabbix7.0监控linux主机案例详解
前言 服务端配置 链接: rocky9.2部署zabbix服务端的详细过程 环境 主机ip应用zabbix-server192.168.10.11zabbix本体zabbix-client192.168.10.12zabbix-agent zabbix-server(服务端已配置) 具体实现过程 zabbix-client配置 安装zabbix-agent 添加扩展包 dnf -y instal…...
2024重生之回溯数据结构与算法系列学习(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
欢迎各位彦祖与热巴畅游本人专栏与博客 你的三连是我最大的动力 以下图片仅代表专栏特色 专栏跑道一 ➡️ MYSQL REDIS Advance operation 专栏跑道二➡️ 24 Network Security -LJS 专栏跑道三 ➡️HCIP;H3C-SE;CCIP——LJS[华为、华三、思科高级网络]…...
django drf 过滤器
排序 代码: from rest_framework.generics import ListAPIView from rest_framework.filters import OrderingFilterclass TestListAPIView(ListAPIView):queryset models.Course.objects.filter(is_deleteFalse).all()serializer_class serializers.TestModelS…...
蓝桥杯—STM32G431RBT6(RTC时钟获取时间和日期)
一、RTC是什么,有什么用? 在 STM32 中,RTC(Real-Time Clock,实时时钟)主要有以下作用: 时间保持:即使在系统断电情况下,也能持续记录时间。(需要纽扣电池供电…...
DriveVLM 论文学习
论文链接:https://arxiv.org/abs/2402.12289 解决了什么问题? 自动驾驶对交通行业有着革命性的作用,实现 FSD 的一个主要障碍就是场景理解。场景理解涉及在复杂且不可预测的环境中进行导航,这些环境可能包括恶劣的天气条件、复杂…...
Unity3D 客户端多开
Unity3D 实现客户端多开 客户端多开 最近在做好友聊天系统,为了方便测试,需要再开一个客户端。 简单的方法,就是直接拷贝一个新的项目,但是需要很多时间和占用空间。 查阅了网络资料,发现有一种软链接,…...
使用代理IP数据采集都需要注意那些?
“在当今大数据时代,数据采集成为了企业决策和个人研究的重要依据。然而频繁访问目标网站往往会引发IP被封锁的风险,这时使用代理IP就显得尤为重要。但代理IP的使用并非毫无风险,以下是使用代理IP进行数据采集时需要注意的几个关键事项。” 一…...
城市大脑:智慧城市的神经中枢——典型实践与经验启示
随着信息技术的飞速发展,智慧城市已成为全球城市转型升级的重要方向。“城市大脑”作为智慧城市的核心引擎,正以其强大的数据处理能力、智能决策支持和跨领域协同优势,引领着城市管理与服务的深刻变革。本文将深入探讨几个具有代表性的“城市…...
嵌入式中CW32多功能测试笔实现
前言 起心动念 在日常的硬件调试工作中,我们最常使用的仪器仪表可能就是万用表了,虽然万用表号称“万用”,但大部分时候,我们需要使用到的功能无非是电压测量和通断测量。 作为调试的“得力干将”,万用表有时候也会存在存在一些缺点和局限性,比如:体积较大不便于携带…...
Python 时间占位符:毫秒的使用
Python 时间占位符:毫秒的使用 在 Python 中,处理时间和日期是一个非常常见的任务。在进行时间格式化时,使用占位符来表示特定的时间单位是非常重要的。特别是毫秒(ms),它在许多应用中扮演着关键角色&…...
深度学习:(七)梯度下降法在神经网络中的应用
梯度下降法在神经网络中的应用 事先规定: 用 n n n 表示个数(维度): n [ 0 ] n x n^{[0]}n_x n[0]nx ,表示单个训练样本 x x x 的元素个数; n [ 1 ] n^{[1]} n[1] 表示隐藏层 1 1 1 的单元(节点&am…...
HarmonyOS---权限和http/Axios网络请求
网络请求(http,axios) 目录 一、应用权限管理1.1权限的等级1.2授权方式1.3声明权限的配置1.4如何向用户进行申请 二、内置http请求使用三、Axios请求使用(建议)3.1 使用方式一3.2 使用方式二(建议) 一、应用权限管理 应用权限保护…...
信号量SEM
前提 1.信号量的本质是一把计数器 2.申请信号本质就是预订资源 3.PV操作是原子的! 将一个公共资源当做整体访问-->锁 如果公共资源不当做整体使用,多进程可以并发的访问公共资源,但不是同一个区域,为了将资源均分,所以有了…...
828华为云征文 | 基于华为云Flexus云服务器X搭建部署——AI知识库问答系统(使用1panel面板安装)
🚀对于企业来讲为什么需要华为云Flexus X来搭建自己的知识库问答系统??? 【重塑知识边界,华为云Flexus云服务器X引领开源问答新纪元!】 🌟 解锁知识新动力,华为云Flexus云服务器X携…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
