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.payorder.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.createuser.delete,但不匹配 user.create.wechat);
    • #(井号):匹配 0个或多个任意段(例如 Binding Key = user.#,可匹配 useruser.createuser.create.wechat)。
  • 匹配逻辑:仅当 Routing Key 与 Binding Key 的通配符规则完全匹配时,消息才会被路由到队列。

2. 适用场景

需要 按“主题”分类路由 的场景,例如:

  • 多维度业务消息(如“用户相关消息”包含 user.createuser.deleteuser.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. 核心特性

  • 匹配规则
    1. 绑定队列时,需设置一组“头部键值对”(如 {"type":"log", "level":"error"}),并指定匹配模式(x-match):
      • x-match = all(默认):消息的 Header 需包含 所有 绑定的键值对,才匹配;
      • x-match = any:消息的 Header 只需包含 任意一个 绑定的键值对,即可匹配。
    2. 生产者发送消息时,无需指定 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。

posted @ 2025-10-13 15:14  疯狂马铃薯  阅读(4)  评论(0)    收藏  举报