rabbitmq入门
消息队列中间件
消息队列中间件,也可以称为消息队列或者消息中间件。它一般有两种传递模式:点对点
模式和发布/订阅模式。点对点模式是基于队列的,消息生产者发送消息到队列,消息消费者从队列中接收消息,队列的存在使得消息的异步传输成为可能。
发布订阅模式定义了如何向一个内容节点发布和订阅消息,这个内容节点称为主题topic
,主题可以认为是消息传递的中介,消息发布者将消息发布到某个主题,而消息订阅者则从主题中订阅消息。主题使得消息的订阅者与消息的发布者互相保持独立,不需要进行接触即可保证消息的传递,发布/订阅模式在消息的一对多广播时采用。
简单示例
应用程序A与应用程序B通过使用消息中间件的应用程序编程接口发送消息来进行通信
消息中间件将消息路由给应用程序B,这样消息就可存在于完全不同的计算机上。消息中间件负责处理网络通信,如果网络连接不可用,消息中间件会存储消息,直到连接变得可用,再将消息转发给应用程序B。灵活性的另一方面体现在,当应用程序A发送其消息时,应用程序B甚至可用处于不运行状态,消息中间件将保留这份消息,直到应用程序B开始执行并消息消息,这样还防止了应用程序A因为等待应用程序B消费消息而出现阻塞。这种异步通信方式要求应用程序的设计与现在大多数应用不同。
安装
1.依赖安装
2.erlang编译安装
3.配置erlang环境
4.安装rabbitmq
5.运行
6.检查是否启动成功
7.查看集群节点命令
go操作rabbitmq
0.官网代码示例(参考)
1.添加新用户,用户名为root,密码为root
2.为root用户设置所有权
3.设置root用户为管理员角色
4.生产者客户端代码
5.消费者代码
6.启动
rabbitmq相关概念介绍
rabbitmq整体上是一个生产者与消费者模型,主要负责接收、存储和转发消息。可以把消息传递的过程想象成:当你将一个包裹送到邮局,邮局会暂存并最终将邮件通过邮递员送到收件人的手上,rabbitmq就好比邮局、邮箱和邮递员组成一个系统。从计算机术语层面来说,rabbitmq模型更像是一种交换机模型。
整体模型架构
生产者和消费者
Producer:生产者,就是投递消息的一方。
生产者创建消息,然后发布到rabbitmq中,消息一般可以包含2个部分:消息体和标签(label)。消息体也可以称之为payload,在实际应用中,消息体一般是一个带有业务逻辑结构的数据,比如一个json字符串。当然可以进一步对这个消息体进行序列化操作。消息的标签从来表述这条消息,比如一个交换器的名称和一个路由键。生产者把消息交由rabbitmq,rabbitmq之后会根据标签把消息发送给感兴趣的消费者。
Consumer:消费者,就是接收消息的一方
消费者连接到rabbitmq服务器,并订阅到队列上。当消费者消费一条消息时,只是消费消息的消息体(payload)。在消息路由的过程中,消息的标签会丢弃,存入到队列中的消息只有消息体,消费者也只会消费到消息体,也就不知道消息的生产者是谁,当然消费者也不需要知道。
Broker:消息中间件的服务节点
对于rabbitmq来说,一个rabbitmq broker可以简单的看作一个rabbitmq服务节点,或者rabbitmq服务实例。大多数情况下也可以将一个rabbitmq broker看作一台rabbitmq服务器
下图展示了生产者将消息存入rabbitmq broker,以及消费者从broker中消费数据的整个流程。
队列
Queue:队列,是rabbitmq的内部对象,用于存储消息。
rabbitmq中消息都只能存储在队列中,这一点和Kafka这种消息中间件相反。Kafka将消息存储在topic(主题)这个逻辑层面,而相对应的队列逻辑只是topic实际存储文件中的位移标识。rabbitmq的生产者生产消息并最终投递到队列中,消费者可以从队列中获取消息并消费。
多个消费者可以订阅同一个队列,这时队列中的消息会被平均分摊(Round-Robin,即轮询)给多个消费者进行处理,而不是每个消费者都收到所有的消息并处理
交换器、路由键、绑定
Exchange;交换器。在下图中我们暂时可以理解成生产者将消息投递到队列中,实际上这个在rabbitmq中國不会发生。真实情况是,生产者将消息发送到Exchange(交换器,通常也可以用过大写的"X"来表示),由交换器将消息路由到一个由多个队列中。如果路由不到,或许会返回给生产者,或许直接丢弃。这里可以将rabbitmq中的交换器看做一个简单的实体。
rabbitmq中的交换器有四种类型,不同的类型有着不同的路由策略。
RoutingKey:路由键。生产者将消息发给交换器的时候,一般会指定一个RoutingKey,用来指定这个消息的路由规则,而这个RoutingKey需要与交换器类型和绑定键(BindingKey)联合使用才能最终生效。
在交换器类型和绑定键(BindingKey)固定的情况下,生产者可以在发送消息给交换器时,通过指定RoutingKey来决定消息流向哪里。
Binding:绑定。rabbitmq中通过绑定将交换器与队列关联起来,在绑定的时候一般会指定一个绑定键(BindingKey),这样rabbitmq就知道如何正确的将消息路由到队列了。
生产者将消息发送给交换器时,需要一个RoutIngKey,当BindingKey和RoutingKey相匹配时,消息会被路由到对应的队列中。在绑定多个队列到同一个交换器的时候,这些绑定允许使用相同的BindingKey。BindingKey并不是在所有的情况都生效,它依赖于交换器类型,比如fanout类型的交换器就会无视BindIngKey,而是将消息路由到所有绑定到该交换器的队列中。
交换器相当于投递包裹的邮箱,RoutingKey相当于填写在包裹上的地址,BindingKey相当于包裹的目的地,当填写在包裹上的地址和实际想要投递的地址想匹配时,那么这个包裹就会被正确投递到目的地,最后这个目的地的主人(队列)可以保留这个包裹。如果填写的地址出错,邮递员不能正确投递到目的地,包裹可能会退回给寄件人。
交换器类型
rabbitmq常用的交换器类型有fanout、direct、topic、headers这四种。amqp协议里还提到另外两种类型:System和自定义.
fanout:它会把所有发送到该交换器的消息路由到所有与该交换器绑定的队列中。
direct:direct类型的交换器路由规则也很简单,它会把消息路由到那些BindingKey和RoutingKey完全匹配的队列中。
下图为例,交换器的类型为direct,如果我们发送一条消息,并在发送消息的时候设置路由键为"warnning",则消息会路由到Queue1和Queue2
如果在发送消息的时候设置路由键为"info"或者"debug",消息只会路由到Queue2。如果以其他的路由键发送消息,则消息不会路由到这两个队列中。
topic:前面讲到direct类型的交换器路由规则是完全匹配BindingKey和RoutingKey,但是这种严格的匹配方式在很多情况下不能满足实际业务的需求。topic类型的交换器在匹配规则上进行了扩展,它与direct类型的交换器相似,也是将消息路由到BindingKey和RoutingKey相匹配的队列中,但这里的匹配规则有些不同,它约定
- RoutIngKey为一个点号".",分隔的字符串(被点号分隔开的每一段独立的字符串称为一个单词。)
- BindingKey和RoutingKey一样也是点号"."分隔的字符串
- BindingKey中可以存在两种特殊字符串""和"#",用于做模糊匹配,其中"#"用于匹配一个单词,""用于匹配多规格单词(可以是零个)
下图配置为例
- 路由键为"com.rabbitmq.client"的消息会同时路由到Queue1和Queue2
- 路由键为"com.hidden.client"的消息只会路由到Queue2中
- 路由键为"com.hidden.demo"的消息只会路由到Queue2中
- 路由键为"go.rabbitmq.demo"的消息只会路由到Queue1中
- 路由键为"go.util.concurrent"的消息将会被丢弃或者返回给生产者(需要设置mandatory参数),因为它没有匹配任何路由键
headers:headers类型的交换器不依赖于路由键的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。在绑定队列和交换器时制定一组键值对,当发送消息到交换器时,rabbitmq会获取到该消息的headers(也是一个键值对的形式),对比其中的键值对是否完全匹配队列和交换器绑定时指定的键值对,如果完全匹配则消息会路由到该队列,否则不会路由到该队列。headers类型的交换器性能会变差,而且也不实用,基本上不会看到它的存在。
rabbitmq运转流程
生产者发送消息的时候
1.生产者连接到rabbitmq broker,建立一个连接,开启一个管道
2.生产者声明一个交换器,并设置相关属性,比如交换器类型,是否持久化
3.生产者声明一个队列并设置相关属性,比如是否排他,是否持久化,是否自动删除等
4.生产者通过路由键将交换器和队列绑定起来
5.生产者发送消息至rabbitmq broker,其中包含路由键,交换器等信息
6.相应的交换器根据接收到的路由键查找相匹配的队列
7.如果找到,则将从生产者发送过来的消息存入相应的队列中
8.如果没有找到,则根据生产者配置的属性选择丢弃还是回退给生产者
9.关闭管道
10.关闭连接
消费者接收消息的过程
1.消费者连接到rabbitmq broker,建立一个连接,开启一个管道
2.消费者向rabbitmq broker请求消费相应的队列中的消息,可能会设置相应的回调函数,以及做一些准备工作
3.等待rabbitmq broker回应并投递相应队列中的消息,消费者接收消息
4.消费者确认ack接收到的消息
5.rabbitmq从队列中删除相应已经被确认的消息
6.关闭管道
7.关闭连接
问题:为什么要引入管道
假设一个应用程序中有很多线程需要从rabbitmq中消费消息,或者生产消息,你们必然要建立很多个连接,也就是许多个TCP连接。然而对于操作系统而言,建立和销毁TCP连接都是非常昂贵的开销,如果遇到使用高峰,性能瓶颈也随之显现。rabbitmq采用NIO的做法,选择TPC连接复用,不仅可以减少性能开销,同时也便于管理
amqp协议介绍
rabbitmq是遵从amqp协议的,换句话说,rabbitmq就是amqp协议的Erlang的实现。amqp的模型架构和rabbitmq的模型架构是一样的,生产者将消息发送给交换器,交换器和队列绑定。当生产者发送消息时所携带的RoutingKey与绑定时的BindingKey相匹配时,消息即被存入相应的队列中。消费者可以订阅相应的队列来获取消息
amqp协议本身包括三层
- Module Layer:位于协议最高层,主要定义了一些供客户端调用的命令,客户端可以利用这些命令实现自己的业务逻辑。例如,客户端可以使用ch.QueueDeclare命令一个队列或者使用ch.Consume订阅消费一个队列中的消息
- Session Layer:位于中间层,主要负责将客户端的命令发送给服务器,再将服务端的应答返回给客户端,主要为客户端与服务器之间的通信提供可靠性同步机制和错误处理
- Transport Layer:位于最底层,主要传输二进制数据流,提供帧的处理、管道复用、错误检测和数据表示等。
amqp说到底还是一个通信协议,通信协议都会涉及报文交互,从low-level举例来说,amqp本身是应用层的协议,其填充于TCP协议层数据部分。而从high-level来说,amqp是通过协议命令进行交互的。amqp协议可以看作一系列结构化命令的集合,这里的命令代表一种操作,类似于HTTP中的方法(GET/POST/PUT/DELETE)等。
amqp流程过程图
生产者
消费者
__EOF__

本文链接:https://www.cnblogs.com/weiweivip666/p/16578445.html
关于博主:可能又在睡觉
版权声明:转载请注明出处
声援博主:如果看到我睡觉请喊我去学习
-------------------------------------------
个性签名:代码过万,键盘敲烂!!!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人