RabbitMq Exchange模式
RabbitMQ 的 Exchange(交换机) 是消息路由的核心组件,它接收生产者发送的消息,并根据自身类型(默认模式)和绑定规则(Binding Key)将消息路由到对应的队列(Queue)。RabbitMQ 提供 4种核心默认交换机类型,每种类型对应不同的路由逻辑,适用于不同业务场景。以下从 类型定义、路由规则、适用场景、示例 四方面详细介绍:
一、Direct Exchange(直连交换机):精准匹配,一对一路由
Direct 是最基础的交换机类型,核心逻辑是 “消息的 Routing Key 与绑定的 Binding Key 完全匹配”,仅当两者字符完全一致时,消息才会被路由到对应队列。
1. 核心特性
- 路由规则:生产者发送消息时指定
Routing Key
(如order.pay
),交换机仅将消息转发给 Binding Key 与 Routing Key 完全相同 的队列。 - 绑定关系:一个队列可通过多个 Binding Key 绑定到 Direct 交换机(例如队列绑定
order.pay
和order.refund
,可接收这两个 Routing Key 的消息);多个队列也可绑定相同的 Binding Key(此时消息会被广播到所有匹配队列,类似“多播”)。
2. 适用场景
需要 精准路由 的场景,例如:
- 业务模块拆分(如“订单支付”消息仅路由到“支付处理队列”,“订单退款”消息仅路由到“退款处理队列”);
- 任务分发(如特定类型的任务分配给指定worker队列)。
3. 工作流程示例
生产者 → Direct交换机(名称:direct_exchange)
↓ 发送消息时指定 Routing Key = "order.pay"
Direct交换机 → 检查绑定关系:
- 队列A 绑定 Binding Key = "order.pay" → 消息路由到队列A
- 队列B 绑定 Binding Key = "order.refund" → 不匹配,不路由
- 队列C 绑定 Binding Key = "order.pay" → 消息路由到队列C
最终:队列A和队列C接收消息,队列B无消息
二、Fanout Exchange(扇出交换机):无差别广播,一对多路由
Fanout 是“广播型”交换机,核心逻辑是 “忽略 Routing Key,将消息路由到所有与该交换机绑定的队列”,无需匹配规则,只要队列绑定了交换机,就能收到消息。
1. 核心特性
- 路由规则:完全不处理 Routing Key(即使生产者指定了 Routing Key,交换机也会忽略),仅根据“交换机-队列”的绑定关系,将消息复制并转发给 所有绑定的队列。
- 效率:路由逻辑最简单,效率最高,适合需要“全量通知”的场景。
2. 适用场景
需要 广播消息 的场景,例如:
- 系统通知(如服务启动/下线通知、全局配置更新,所有相关服务都需接收);
- 日志收集(如应用日志同时发送到“实时分析队列”和“归档存储队列”);
- 事件同步(如用户注册成功后,同步触发“发送欢迎短信”“创建用户档案”“添加积分”等多个任务)。
3. 工作流程示例
生产者 → Fanout交换机(名称:fanout_exchange)
↓ 发送消息(即使指定 Routing Key = "any",也会被忽略)
Fanout交换机 → 检查绑定关系:
- 队列1 绑定该交换机 → 消息路由到队列1
- 队列2 绑定该交换机 → 消息路由到队列2
- 队列3 未绑定该交换机 → 不路由
最终:队列1和队列2均接收消息(消息为复制后的两份)
三、Topic Exchange(主题交换机):模糊匹配,按“主题”路由
Topic 是“灵活匹配型”交换机,核心逻辑是 “通过通配符匹配 Routing Key 与 Binding Key”,支持按“主题”批量路由消息,兼顾精准性和灵活性。
1. 核心特性
- 通配符规则:Routing Key 和 Binding Key 需满足“多段字符串”格式(段之间用
.
分隔,如user.create.wechat
,每段代表一个“维度”,如业务类型、操作、渠道),支持两种通配符:*
(星号):匹配 1个任意段(例如 Binding Key =user.*
,可匹配user.create
、user.delete
,但不匹配user.create.wechat
);#
(井号):匹配 0个或多个任意段(例如 Binding Key =user.#
,可匹配user
、user.create
、user.create.wechat
)。
- 匹配逻辑:仅当 Routing Key 与 Binding Key 的通配符规则完全匹配时,消息才会被路由到队列。
2. 适用场景
需要 按“主题”分类路由 的场景,例如:
- 多维度业务消息(如“用户相关消息”包含
user.create
、user.delete
、user.update
,可通过 Binding Key =user.#
接收所有用户消息,或通过user.create.*
仅接收用户创建的细分消息); - 跨模块消息分发(如“订单消息”按地区拆分,Binding Key =
order.#.beijing
仅接收北京地区的订单消息)。
3. 工作流程示例
生产者 → Topic交换机(名称:topic_exchange)
↓ 发送消息,指定 Routing Key = "user.create.wechat"
Topic交换机 → 检查绑定关系:
- 队列A 绑定 Binding Key = "user.create.*" → 匹配(* 匹配 "wechat")→ 路由到A
- 队列B 绑定 Binding Key = "user.#" → 匹配(# 匹配 "create.wechat")→ 路由到B
- 队列C 绑定 Binding Key = "user.*.alipay" → 不匹配(Routing Key 第三段是 "wechat")→ 不路由
最终:队列A和队列B接收消息,队列C无消息
四、Headers Exchange(头部交换机):按消息头匹配,忽略Routing Key
Headers 是“非 Key 匹配型”交换机,核心逻辑是 “忽略 Routing Key,通过消息的 Header 属性(键值对)匹配绑定规则”,适合无法通过字符串 Key 匹配,需多维度属性筛选的场景。
1. 核心特性
- 匹配规则:
- 绑定队列时,需设置一组“头部键值对”(如
{"type":"log", "level":"error"}
),并指定匹配模式(x-match
):x-match = all
(默认):消息的 Header 需包含 所有 绑定的键值对,才匹配;x-match = any
:消息的 Header 只需包含 任意一个 绑定的键值对,即可匹配。
- 生产者发送消息时,无需指定 Routing Key,只需在消息 Header 中设置对应的键值对。
- 绑定队列时,需设置一组“头部键值对”(如
- 灵活性:支持多维度属性匹配(如同时按“消息类型”“优先级”“地区”筛选),但路由逻辑较复杂,效率低于前三种类型。
2. 适用场景
需要 多维度属性筛选消息 的场景,例如:
- 日志分级筛选(如“仅接收类型为 error、地区为 Shanghai 的日志”,绑定规则
{"type":"log", "level":"error", "region":"Shanghai"}
,x-match=all
); - 多条件任务分发(如“仅将优先级为 high、归属团队为 A 的任务分配给队列1”)。
3. 工作流程示例
生产者 → Headers交换机(名称:headers_exchange)
↓ 发送消息,Header 设置为 {"type":"log", "level":"error", "region":"Beijing"}
Headers交换机 → 检查绑定关系:
- 队列1 绑定:键值对 {"type":"log", "level":"error"},x-match=all → 消息Header包含这两个键值对 → 路由到1
- 队列2 绑定:键值对 {"region":"Shanghai", "level":"error"},x-match=all → 消息region是Beijing,不匹配 → 不路由
- 队列3 绑定:键值对 {"type":"log", "priority":"high"},x-match=any → 消息包含"type":"log" → 匹配 → 路由到3
最终:队列1和队列3接收消息,队列2无消息
四、默认交换机(Default Exchange):特殊的Direct交换机
除了上述4种类型,RabbitMQ 还有一个 内置的“默认交换机”(名称为空字符串 ""
),本质是一个 Direct 交换机,但有特殊规则:
- 无需手动创建,默认存在;
- 队列创建时,若未指定绑定的交换机,会自动与默认交换机绑定,且 Binding Key 等于 队列名称;
- 生产者发送消息时,若未指定交换机(即
exchange = ""
),消息会被发送到默认交换机,此时 Routing Key 需等于队列名称,才能路由到对应队列(例如 Routing Key = "queue1",则消息路由到名称为 "queue1" 的队列)。
示例:channel.basicPublish("", "queue1", null, message.getBytes())
→ 消息通过默认交换机,路由到名称为 "queue1" 的队列。
总结:4种核心交换机类型对比
交换机类型 | 路由依据 | 匹配规则 | 优点 | 适用场景 |
---|---|---|---|---|
Direct | Routing Key + Binding Key | 完全一致 | 精准、高效 | 一对一任务分发、精准业务路由 |
Fanout | 交换机-队列绑定关系 | 无(广播所有绑定队列) | 最简单、广播效率高 | 系统通知、日志收集、事件同步 |
Topic | Routing Key + Binding Key | 通配符(* 匹配1段,# 匹配多段) | 灵活、支持按主题分类 | 多维度业务消息、分类路由 |
Headers | 消息Header属性 | 键值对匹配(all/any模式) | 多条件筛选、忽略Key | 多维度属性筛选的复杂场景 |
实际开发中,需根据业务的“路由精度需求”和“消息分发范围”选择合适的交换机类型,例如:简单通知用 Fanout,精准任务用 Direct,多维度分类用 Topic,复杂属性筛选用 Headers。
本文来自博客园,作者:疯狂马铃薯,转载请注明原文链接:https://www.cnblogs.com/hr0552/p/19138555