RabbitMQ简介
消息队列
消息队列(Message Queue)是一种应用间的通信方式,消息发送后可以立即返回,由消息系统来确保消息的可靠传递。
消息发布者只管把消息发布到MQ中而不用管谁来取,消息使用者只管从MQ中取消息而不管是谁发布的。这样发布者和使用者都不用知道对方的存在。
RabbitMQ特点
RabbitMQ是一个由Erlang语言开发的AMQP的开源实现
AMQP:Advanced Message Queue,高级消息队列协议。它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。
RabbitMQ具备以下特点:
-
可靠性(Reliability)
RabbitMQ使用一些机制来保证可靠性,如持久化、传输确认、发布确认。 -
灵活的路由(Flexible Routing)
在消息进入队列之前,通过Exchange来路由消息的。
对于典型的路由功能,RabbitMQ已经提供了一些内置的Exchange来实现。
针对更复杂的路由功能,可以将多个Exchange绑定在一起,也通过插件机制实现自己的Exchange。 -
消息集群(Clustering)
多个RabbitMQ服务器可以组成一个集群,形成一个逻辑Broker。 -
高可用(Highly Available Queues)
队列可以在集群中的机器上进行镜像,使得在部分节点出问题的情况下队列仍然可用。 -
多种协议(Multi-protocal)
RabbitMQ支持多种消息队列协议,比如STOMP、MQTT等等。 -
多语言客户端(Many Clients)
RabbitMQ几乎支持所有常用语言,比如Java、.NET、Ruby等等。 -
管理界面(Management UI)
RabbitMQ提供了一个易用的用户界面,使得用户可以监控和管理消息Broker的许多方面。 -
跟踪机制(Tracing)
如果消息异常,RabbotMQ提供了消息跟踪机制,使用者可以找出发生了什么。 -
插件机制(Plugin System)
RabbitMQ提供了许多插件,来从多方面进行扩展,也可以编写自己的插件。
消息模型基本概念
所有 MQ 产品从模型抽象上来说都是一样的过程:
消费者(consumer)订阅某个队列。生产者(producer)创建消息,然后发布到队列(queue)中,最后将消息发送到监听的消费者。
RabbitMQ基本概念
-
Message
消息,消息是不具名的,它由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。 -
Publisher
消息的生产者,也是一个向交换器发布消息的客户端应用程序。 -
Exchange
交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列。 -
Bingding
绑定,用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可将交换器理解成一个由绑定构成的路由表。 -
Queue
消息队列,用来保存消息直接发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。 -
Connection
网络连接,比如一个TCP连接。 -
Channel
信道,多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内的虚拟连接,AMQP命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。
因为对于操作系统来说建立和销毁TCP都是非常昂贵的开销,所以引入了信道的概念,以复用一条TCP连接。 -
Consumer
消息的消费者,表示一个从消息队列中取得消息的客户端应用程序。 -
Virtual Host
虚拟主机,表示一批交换器,消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。每个vhost本质上就是一个mini版的RabbitMQ服务器,拥有自己的队列、交换器、绑定和权限机制。
vhost是AMQP概念的基础,必须在连接时指定,RabbitMQ默认的vhost是/。 -
Broker
表示消息队列服务器实体。
RabbitMQ集群
RabbitMQ最优秀的功能之一就是内建集群,这个功能设计的目的是允许消费者和生产者在节点崩溃的情况下继续运行,以及通过添加更多的节点来线性扩展消息通信吞吐量。RabbitMQ内部利用Erlang提供的分布式通信框架OTP来满足上述需求,使客户端在失去一个RabbitMQ节点连接的情况下,还是能够重新连接到集群中的任何节点继续生产、消费消息。
RabbitMQ会始终记录以下四种类型的内部元数据:
-
队列元数据
包括队列名称和它们的属性,比如是否可持久化,是否自动删除。 -
交换器元数据
交换器名称、类型、属性。 -
绑定元数据
内部是一张表格记录如何将消息路由到队列。 -
vhost元数据
为vhost内部的队列、交换器、绑定提供命名空间和安全属性。
在单一节点中,RabbitMQ 会将所有这些信息存储在内存中,同时将标记为可持久化的队列、交换器、绑定存储到硬盘上。存到硬盘上可以确保队列和交换器在节点重启后能够重建。
而在集群模式下同样也提供两种选择:存到硬盘上(独立节点的默认设置),存在内存中。
如果在集群中创建队列,集群只会在单个节点而不是所有节点上创建完整的队列信息(元数据、状态、内容)。结果是只有队列的所有者节点知道有关队列的所有信息,因此当集群节点崩溃时,该节点的队列和绑定就消失了,并且任何匹配该队列的绑定的新消息也丢失了。还好RabbitMQ 2.6.0之后提供了镜像队列以避免集群节点故障导致的队列内容不可用。
RabbitMQ 集群中可以共享 user、vhost、exchange等,所有的数据和状态都是必须在所有节点上复制的,例外就是上面所说的消息队列。RabbitMQ 节点可以动态的加入到集群中。
当在集群中声明队列、交换器、绑定的时候,这些操作会直到所有集群节点都成功提交元数据变更后才返回。集群中有内存节点和磁盘节点两种类型,内存节点虽然不写入磁盘,但是它的执行比磁盘节点要好。内存节点可以提供出色的性能,磁盘节点能保障配置信息在节点重启后仍然可用,那集群中如何平衡这两者呢?
RabbitMQ 只要求集群中至少有一个磁盘节点,所有其他节点可以是内存节点,当节点加入火离开集群时,它们必须要将该变更通知到至少一个磁盘节点。如果只有一个磁盘节点,刚好又是该节点崩溃了,那么集群可以继续路由消息,但不能创建队列、创建交换器、创建绑定、添加用户、更改权限、添加或删除集群节点。 换句话说集群中的唯一磁盘节点崩溃的话,集群仍然可以运行,但知道该节点恢复,否则无法更改任何东西。
RabbitMQ有四种集群架构:
主备模式
也称为Warren(兔子窝)模式。实现rabbitMQ的高可用集群,一般在并发和数据量不高的情况下,这种模式非常的好用且简单。
也就是一个主/备方案,主节点提供读写,备用节点不提供读写。如果主节点挂了,就切换到备用节点,原来的备用节点升级为主节点提供读写服务,当原来的主节点恢复运行后,原来的主节点就变成备用节点,和activeMQ利用zookeeper做主/备一样,也可以一主多备。
远程模式
远程模式可以实现双活的一种模式,简称shovel模式,所谓的shovel就是把消息进行不同数据中心的复制工作,可以跨地域的让两个MQ集群互联,远距离通信和复制。
shovel就是我们可以把小进行数据中心的复制工作,我们可以跨地域的让两个MQ集群互联。
这是rabbitMQ比较早期的架构模型了,现在很少使用了。
镜像模式
非常经典的mirror镜像模式,保证100%数据不丢失。在实际工作中也是用得最多的,并且实现非常的简单,一般互联网大厂都会构建这种集群模式。
mirror镜像队列,目的是为了保证rabbitMQ数据的高可靠性解决方案,主要就是实现数据的同步,一般来讲是2-3个节点实现数据同步。
对于100%数据可靠性解决方案,一般是采用3个节点。
多活模式
也是实现异地数据复制的主流模式,因为shovel模式配置比较复杂,所以一般来说,实现异地集群都是采用这种双活或者多活模型来实现的。
这种模式需要依赖rabbitMQ的federation插件,可以实现持续的,可靠的AMQP数据通信,多活模式在实际配置和应用非常的简单。
rabbitMQ部署架构采用双中心模式(多中心),那么在两套(或多套)数据中心各部署一套rabbitMQ集群,各中心的rabbitMQ服务除了需要为业务提供正常的消息服务外,中心之间还需要实现部分队列消息共享。
RabbitMQ Management
overview
默认启动页
connections
rabbitmq连接信息
channels
建立在连接基础上的通道,实际开发中链接应为全局变量,通道为线程级
exchanges
交换机维护界面,提供交换机增加和查询功能
queues
消息队列维护,可以对消息队列进行增加、查询操作
admin
管理员用户维护界面,可以增、删、改、查管理员用户
-
生产者通过amqp协议连接RabbitMQ,建立连接。
-
连接上创建信道。
-
信道内创建不同类型的交换器和消息列队,交换器通过Routing key绑定消息列队,并且发布消息存储在列队内。
-
消费者获取连接和信道,在信道内通过消息列队标识(QueueName)启动一个消费者,消费者消费消息。

浙公网安备 33010602011771号