文章目录
- 前言
- 一、RabbitMQ介绍
-
- [1. MQ简介](#1. MQ简介)
- [2. AMQP简介](#2. AMQP简介)
- [3. RabbitMQ简介](#3. RabbitMQ简介)
- 二、RabbitMQ机制
-
- [1. 基础架构](#1. 基础架构)
- [2. 工作过程](#2. 工作过程)
- [3. 交换机类型](#3. 交换机类型)
-
- [1. **Direct exchange(直连交换机)**](#1. Direct exchange(直连交换机))
- [2. **Fanout exchange(扇形交换机)**](#2. Fanout exchange(扇形交换机))
- [3. **Topic exchange(主题交换机)**](#3. Topic exchange(主题交换机))
- [4. **Headers exchange(头交换机)**](#4. Headers exchange(头交换机))
- [5. 交换机小结](#5. 交换机小结)
- [4. 工作模式](#4. 工作模式)
- [三、RabbitMQ Queue](#三、RabbitMQ Queue)
前言
RabbitMQ
RabbitMQ是由erlang语言开发,基于AMQP协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开发中应用非常广泛。
一、RabbitMQ介绍
1. MQ简介
MQ(Message Queue)是一种跨进程的通信机制,用于上下游传递消息。本质是个 FIFO 先进先出的数据结构,只不过队列中存放的内容是 message 。
消息中间件在早已成为企业IT系统内部通信的核心手段。它具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列功能,成为异步RPC的主要手段之一。
中间件的标准用法是生产者生产消息传送到队列,消费者从队列中拿取消息并处理,生产者不用关心是谁来消费,消费者不用关心谁在生产消息。
2. AMQP简介
Advanced Message Queuing Protocol(高级消息队列协议),提供统一的应用层开放标准,为面向消息的中间件设计。最早用于解决金融领域,不同平台之间的消息传递交互问题。
该协议是一种二进制协议,保证客户端与消息中间件传递消息,异步、安全、高效的交互,不受客户端/中间件不同产品、不同开发语言等条件的限制。
主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性高、安全。
3. RabbitMQ简介
RabbitMQ 是实现 AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。
优点
(1)由Erlang语言开发,支持大量协议:AMQP、XMPP、SMTP、STOMP。
(2)支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP 等,支持 AJAX。
(3)性能很好,延时很低,时效性us级,并发能力较强,吞吐量万级。
(4)保证消息可靠性,支持消息的持久化、负载均衡和集群,且集群易扩展。
(5)消息全局有序,支持消息确认机制、灵活的消息分发机制。
(6)支持幂等性,避免消息重复消费。
(7)支持死信队列,形成重新投递与延时发送,达到消息回溯。
(8)自带Web管理界面,运维便捷,没有额外的系统依赖。
(9)安装部署简单,开箱即用,上手容易,功能丰富,强大的社区支持。
缺点
(1)由于牺牲了部分性能来换取稳定性,比如消息的持久化功能,使得RabbitMQ在大吞吐量性能方面不及Kafka和RocketMQ。
(2)由于支持多种协议,使RabbitMQ非常重量级,比较适合企业级开发。
因此,当需要一个性能稳定、低延时、功能强大且易于管理的消息队列可以选择RabbitMQ。如果对消息吞吐量需求很大,且不在乎消息偶尔丢失的情况可以使用Kafka。

二、RabbitMQ机制
1. 基础架构
生产者Producer生产消息发送到交换机Exchange,由交换机分发到指定的队列Queue存储,然后消费者Consumer 从队列获取消息进行消费。

- 消息(Message):客户端与消息中间件传送的数据。
- 生产者(Producer):消息生产者,是向交换机发布消息的客户端应用程序。
- 消费者(Consumer):消息消费者,是从消息队列中接收消息的客户端应用程序。
- 中间件(Broker):接收和分发消息的服务端应用程序,实现AMQP实体服务,如RabbitMQ Server。
- 连接(Connection):客户端应用程序Producer/Consumer和 Broker 之间的TCP/IP网络连接。
- 信道(Channel):进行消息读写的的双向数据流网络通道,是建立在Connection连接之上的轻量级的逻辑连接,可以降低开销,提高效率。一个Connection上可以建立若干个Channel。
- 虚拟主机(Virtual Host):提供资源的逻辑分组和隔离。包含Connection,Exchange,Queue,Binding,权限,策略等。一个Virtual Host可以创建若干个Exchange和Queue。
- 交换机(Exchange):服务端用来接收生产者发送的消息,并根据路由键将这些消息发送给绑定的队列。
- 绑定(Binding):Exchange与Queue间的关联绑定。Consumer将关注的Queue绑定到指定Exchange上,以便Exchange能准确分发消息到指定队列。BindingKey是绑定的规则描述。
- 路由键(Routing Key):路由规则,Exchange用来确定如何路由一个特定的消息。
- 队列(Queue):队列,消息的缓冲存储区。
Binding Key与Routing Key的关系
Binding Key是Exchange和Queue之间的绑定key;
Routing Key是Producer发给Exchange的一个信息;
当Binding Key和Routing Key能对应上时,Exchange将该消息放到相应的Queue中。
服务端broker进行了逻辑分区,划分成很多个虚拟机virtual host,虚拟机中有很多的交换机,交换机绑定到队列上。
在Connection中使用了channel这些管道资源来进行连接,减少资源的消耗。
2. 工作过程
-
发布者(Publisher)发布消息(Message),经由交换机(Exchange)。
-
交换机根据路由规则将收到的消息分发给与该交换机绑定的队列(Queue)。
-
AMQP代理会将消息投递给订阅了此队列的消费者(push API),或者,消费者按照需求主动获取 (pull API)。

注:多个消费者监听同一个队列时,队列中的消息只会被其中一个消费者消费(并不会每个消费者都消费一次)
3. 交换机类型

1. Direct exchange(直连交换机)
Direct:消息中的路由键(routing key)如果和 Binding 中的 binding key 一致,
交换器就将消息发到对应的队列中。它是完全匹配、单播的模式。
- 根据message携带的routing key将message投递给对应绑定键的队列。用来处理消息的单播路由。
- 明确的路由规则:消费端绑定的队列名称必须和消息发布时指定的路由名称一致。

2. Fanout exchange(扇形交换机)
Fanout:每个发到 fanout 类型交换器的消息都会分到所有绑定的队列上去。很像子
网广播,每台子网内的主机都获得了一份复制的消息。fanout 类型转发消息是最快
的。
- 将消息分发到exchange上绑定的所有队列上。一般用来处理消息的广播路由(broadcast routing)。



3. Topic exchange(主题交换机)
topic :topic 交换器通过模式匹配分配消息的路由键属性,将路由键和某个模
式进行匹配,此时队列需要绑定到一个模式上。它将路由键和绑定键的字符串切分成
单词,这些单词之间用点隔开。它同样也会识别两个通配符:符号"#"和符号
""。#匹配 0 个或多个单词,匹配不多不少一个单词。
-
根据routing key和Exchange的类型将message发送到一个或者多个Queue中。一般用来实现各种publish/subscribe,即发布订阅。
-
模式匹配的路由规则:支持通配符。



4. Headers exchange(头交换机)
-
Exchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。
-
headers 匹配 AMQP 消息的 header 而不是路由键,此外 headers 交换器和
direct 交换器完全一致,但性能差很多,目前几乎用不到了
5. 交换机小结
交换机类型 | 交换机名称 | Binding Key | Routing Key | 路由规则 |
---|---|---|---|---|
默认交换机 | 空串,不可修改 | 默认为Queue名称,不可改 | 同Binding Key名称 | Routing Key==Binding Key,严格匹配 |
直连交换机 | 自定义 | 默认为Queue名称,可修改 | 同Binding Key名称 | Routing Key==Binding Key,严格匹配 |
扇形交换机 | 自定义 | 无Binding Key | 无Routing Key | 无Binding Key,自动路由到交换机绑定的所有Queue中 |
主题交换机 | 自定义 | 自定义 | 自定义 | Routing Key==Binding Key,模糊匹配 |
头交换机 | 自定义 | 自定义 | 自定义 | 根据发送的消息内容中的headers属性进行匹配 |
4. 工作模式
- Work-queues工作队列模式

工作队列模式是最简单的RabbitMQ应用场景。
生产者(Producer)往队列(Queue)里投放消息,所有注册到该队列的消费者(Consumer)是竞争关系,队列中的每条消息能且只能被一个消费者消费。
- broadcast广播模式

广播模式采用Fanout Exchange扇形交换机,绑定到交换机上的队列都可以从交换机接收消息。
目标是将每个任务向多个/多组消费者传递。适用于同一消息进行分别处理的场景。
应用场景举例,新会员注册后,需要赠送积分和新会员推送等操作,可以创建一个新建会员Exchange(Fanout),Exchange绑定赠送积分Queue和新会员推送Queue,分别进行相应的逻辑处理。
- routing路由模式

路由模式采用Direct Exchange直连交换机,通过路由键(RoutingKey)将消息路由到绑定键(BindingKey)相同的队列中。
适用于消息按照路由规则进行分别处理的场景,不满足路由规则的消息将丢弃。
应用场景举例,下图日志处理,按照日志级别进行路由,一个队列用来统一处理各级别的日志,一个队列用来特殊处理error级别的严重日志,生成告警等。

- topic主题模式

主题模式采用Topic Exchange主题交换机,也是基于路由键RoutingKey进行路由,匹配模式更加灵活,规则如下:
- RoutingKey必须是单词列表,以"."分隔。
- BindingKey支持通配符。*(星号)可以代替一个单词。#(哈希)可以替代零个或多个单词。
- 不满足路由规则的消息将丢弃。
应用场景举例,按主题模式可以更简单灵活的实现日志处理的功能,支持通配,利于扩展。
三、RabbitMQ Queue
- 仲裁队列
仲裁队列(Quorum Queues)提供队列复制的能力,保障数据的高可用和安全性。使用仲裁队列可以在RabbitMQ节点间进行队列数据的复制,在一个节点宕机时,队列依旧可以正常运行。
仲裁队列适用于队列长时间存在,对队列容错和数据安全要求高,对延迟和队列特性要求相对低的场景。在可能出现消息大量堆积的场景,不推荐使用仲裁队列,因为仲裁队列的写入会造成成倍的磁盘占用。
仲裁队列的消息会优先保存在内存中,使用仲裁队列时,建议定义队列最大长度和最大内存占用,在消息堆积超过阈值时从内存转移到磁盘,以免造成内存高水位。
- 仲裁队列与镜像队列特性差异
特性 | 镜像队列 | 仲裁队列 |
---|---|---|
非持久化队列 | 支持 | 不支持 |
排他队列 | 支持 | 不支持 |
每条消息的持久化 | 每条消息 | 永远 |
队列重平衡 | 自动 | 手动 |
消息超时时间 | 支持 | 不支持 |
队列超时时间 | 支持 | 支持 |
队列长度限制 | 支持 | 支持(除x-overflow: reject-publish-dlx) |
惰性队列 | 支持 | 限制队列长度后支持 |
消息优先级 | 支持 | 不支持 |
消费优先级 | 支持 | 支持 |
死信交换器 | 支持 | 支持 |
动态Policy | 支持 | 支持 |
毒药消息(让消费者无限循环消费)处理 | 不支持 | 支持 |
全局消息预取(Qos) | 支持 | 不支持 |
本文的引用仅限自我学习如有侵权,请联系作者删除。
参考知识
配置RabbitMQ仲裁队列