RabbitMQ 有哪些交换机类型?绑定与路由键如何工作?
结论先行:RabbitMQ 中生产者不直接把消息发给队列,而是发给交换机(Exchange),由交换机按类型与绑定规则把消息路由到一个或多个队列。核心类型有 direct、topic、fanout、headers,binding 是"交换机 → 队列"的路由关系,routing key 是消息携带的路由依据。
一、交换机类型对比
| 类型 | 路由规则 | 典型场景 |
|---|---|---|
| direct | routing key 与绑定键完全相等才路由 | 按路由键精准分发 |
| topic | 绑定键支持通配,* 匹配一个词、# 匹配零到多个词 | 按业务主题灵活订阅 |
| fanout | 广播给所有绑定队列,忽略 routing key | 日志广播、通知扇出 |
| headers | 按消息 header 键值匹配(x-match all/any) | 复杂条件路由 |
| 延迟消息插件 | 插件类型 x-delayed-message,按 x-delay 到期投递 | 延迟任务、定时消息 |
| 默认交换机 | 空字符串 direct,按队列名精确路由 | 简单点对点 |
二、绑定与路由键的工作过程
- 声明:队列和交换机都先声明(durable 决定是否持久化),再建立 binding 关系;
- 发布:生产者发送消息时指定交换机与 routing key;
- 路由:交换机按自身类型匹配绑定键,匹配成功则把消息投递到对应队列;
- 匹配失败:消息没有队列可投递时,若生产者开启了 mandatory 标志会回调返回给生产者,否则消息被丢弃;
- 绑定多对多:一个队列可绑定多个键,多个队列也可绑同一个键,通过绑定组合即可实现精准投递与广播;
- 属性辨析:durable 决定重启后是否保留,autoDelete 决定无绑定或无人消费时是否自动删除,两者经常被混考;
- 方向辨析:binding 声明的是期望收到的键,消息发布携带的是 routing key,二者按交换机类型规则比对;
- 常见错题:fanout 绑定队列时也常配置 routing key,但会被忽略,不要误以为 fanout 会做精确匹配。
三、命令示例
# 声明 topic 交换机并绑定队列,order.created 与 order.cancelled 都路由到 q.order
rabbitmqadmin declare exchange name=ex.order type=topic durable=true
rabbitmqadmin declare queue name=q.order durable=true
rabbitmqadmin declare binding source=ex.order destination=q.order routing_key=order.*
# topic 通配示例:绑定 pay.# 可接收 pay.created、pay.order.success 等所有 pay 前缀消息
rabbitmqadmin declare binding source=ex.order destination=q.pay routing_key=pay.#
常见追问 / 记忆点
- 追问:topic 与 direct 怎么选?答:需要按主题做多级模糊订阅用 topic,一对一精准路由用 direct 更直观。
- 追问:fanout 的 routing key 还有意义吗?答:无意义,fanout 会忽略路由键广播给所有绑定队列。
- 追问:消息发到不存在的交换机怎么办?答:默认交换机通道会报错或按 mandatory 返回,实际应先声明再发送。
- 记忆点:direct 精确相等、topic 通配匹配、fanout 无脑广播、headers 看属性。