本文目录导读:

RabbitMQ 的通配符模式(Topic Exchange)通过 通配符匹配 实现灵活的路由规则,其核心在于 模糊匹配路由键,以下是详细解析:
通配符规则
| 通配符 | 含义 | 示例 |
|---|---|---|
| (星号) | 匹配 一个 单词 | *.orange.* → 匹配 a.orange.b |
| (井号) | 匹配 零个或任意多个 单词 | fruit.# → 匹配 fruit.apple.red 或 fruit |
注意:路由键必须由点号 分隔的单词组成(如
quick.orange.rabbit),通配符不能匹配点号本身。
核心匹配逻辑
- *`**:占位一个单词,不能为空。
- :匹配剩余的所有部分,可以为空。
- 路由键通常被设计为 层级结构,如:
lazy.orange.rabbit。
代码示例(Java Client)
生产者(发送消息)
// 声明 Topic Exchange
channel.exchangeDeclare("topic_logs", "topic");
// 发送不同路由键的消息
channel.basicPublish("topic_logs", "quick.orange.rabbit", null, "消息1".getBytes());
channel.basicPublish("topic_logs", "lazy.orange.elephant", null, "消息2".getBytes());
channel.basicPublish("topic_logs", "quick.orange.fox", null, "消息3".getBytes());
channel.basicPublish("topic_logs", "lazy.brown.fox", null, "消息4".getBytes());
消费者(绑定队列)
消费者 A:匹配所有 *.orange.*
channel.queueBind(queueName, "topic_logs", "*.orange.*"); // 将收到:quick.orange.rabbit, lazy.orange.elephant, quick.orange.fox
消费者 B:匹配所有 *.*.rabbit 和 lazy.#
channel.queueBind(queueName, "topic_logs", "*.*.rabbit"); channel.queueBind(queueName, "topic_logs", "lazy.#"); // 将收到:quick.orange.rabbit (*.*.rabbit), lazy.orange.elephant (lazy.#), lazy.brown.fox (lazy.#)
常见匹配场景与结果
| 路由键 | 绑定键 *.orange.* |
绑定键 lazy.# |
绑定键 *.*.rabbit |
|---|---|---|---|
quick.orange.rabbit |
✅ 匹配 | ✅ 匹配 | |
lazy.orange.elephant |
✅ 匹配 | ✅ 匹配 | |
quick.orange.fox |
✅ 匹配 | ||
lazy.brown.fox |
✅ 匹配 | ||
lazy.pink.rabbit |
✅ 匹配 | ✅ 匹配 | |
quick.brown.fox |
|||
orange |
特殊注意事项
- 无匹配默认丢弃:如果消息的路由键不与任何队列的绑定键匹配,消息会被丢弃。
- 绑定键不能包含空格: 或 等是合法组合。
- 的贪婪性:
#.orange.#会匹配任意包含 orange 的路由键,包括orange本身。 - 性能提示: 比 的匹配成本稍高(需遍历剩余路径),但通常可忽略。
实际应用场景
- 日志收集:按日志级别和模块路由(如
error.database、info.web) - 事件分发:按地理位置/业务类型分发(如
europe.order.created) - 物联网数据:按设备类型/传感器路由(如
temperature.humidity.sensor1)
- *` 匹配 一个** 单词
- 匹配 零个或多个 单词
- 使用点号 分隔的层次结构定义路由键
- 支持 多绑定键(一个队列可绑定多个通配符模式)
通过灵活组合 和 ,可以实现高度定制化的消息路由,满足大部分模糊匹配需求。