消息队列 RabbitMQ 交换机类型
FreeGuideOnline
最新
2026-07-08
python
创建 direct 类型交换机
channel.exchange_declare(exchange='logs', exchange_type='direct')
将队列绑定到交换机,绑定键为 'error'
channel.queue_bind(exchange='logs', queue='error_queue', routing_key='error')
生产者发送消息,路由键为 'error'
channel.basic_publish(exchange='logs', routing_key='error', body='System failure!')
### 2. Fanout 交换机(扇出交换机)
#### 路由规则
Fanout 交换机会**忽略路由键**,直接将消息广播到所有绑定的队列。它是最简单的交换机类型,只管“复制”消息给每一个知道我的队列。
#### 特点
- 所有绑定队列都会收到消息
- 路由键在绑定和发送过程中均被忽略
- 性能极高,因为不需要匹配逻辑
#### 使用场景
- 广泛的消息广播,如系统通知、配置更新
- 实时数据流的多路分发
#### 示例
```python
# 创建 fanout 类型交换机
channel.exchange_declare(exchange='news', exchange_type='fanout')
# 队列绑定(无需指定 routing_key)
channel.queue_bind(exchange='news', queue='queue1')
channel.queue_bind(exchange='news', queue='queue2')
# 生产者发送消息,路由键可以为空
channel.basic_publish(exchange='news', routing_key='', body='Breaking news!')
3. Topic 交换机(主题交换机)
路由规则
Topic 交换机根据模式匹配规则将消息路由到队列。绑定键可以使用通配符:
*(星号)代表恰好一个词。#(井号)代表零个或多个词。
消息的路由键必须是若干个单词,单词之间用点(.)分隔。例如 "stock.usd.nyse" 或 "weather.europe.berlin"。
绑定示例
假设交换机 events,队列 A 绑定键为 *.critical.*,队列 B 绑定键为 alert.#。
- 消息路由键
db.critical.error匹配队列 A 和队列 B(#匹配所有后缀)。 - 消息路由键
alert.system.cpu只匹配队列 B。 - 消息路由键
info.debug.log不匹配任何队列。
使用场景
- 灵活的多条件订阅,如按地区、严重级别发布日志
- 事件驱动架构中复杂路由需求
示例
# 创建 topic 交换机
channel.exchange_declare(exchange='topics', exchange_type='topic')
# 绑定队列,使用通配符
channel.queue_bind(exchange='topics', queue='queue1', routing_key='*.error')
channel.queue_bind(exchange='topics', queue='queue2', routing_key='db.#')
# 生产者发送
channel.basic_publish(exchange='topics', routing_key='db.error', body='DB failure')
4. Headers 交换机(头交换机)
路由规则
Headers 交换机不依赖路由键,而是根据消息的**头属性(Headers)**进行匹配。它使用与消息相同的 header 键值对进行匹配,并支持复杂的条件(例如 x-match 控制全部匹配还是任意匹配)。
- 当
x-match = all(默认),所有指定的 header 键值对必须完全匹配。 - 当
x-match = any,只要有一个 header 键值对匹配即可。
特点
- 路由键被忽略,路由逻辑完全由 headers 决定
- 支持更丰富的匹配条件,但性能略低于其他类型
- 可以处理结构化的多维度路由
使用场景
- 需要基于消息属性(如来源、类型、优先级)动态路由的场景
- 替代 topic 交换机完成更复杂的多维过滤
示例
# 创建 headers 交换机
channel.exchange_declare(exchange='headers_logs', exchange_type='headers')
# 绑定队列,并指定 headers 匹配条件
arguments = {
'x-match': 'all',
'format': 'pdf',
'type': 'report'
}
channel.queue_bind(exchange='headers_logs', queue='queue1', routing_key='', arguments=arguments)
# 生产者设置消息 headers
properties = pika.BasicProperties(headers={'format': 'pdf', 'type': 'report'})
channel.basic_publish(exchange='headers_logs', routing_key='', body='Report data', properties=properties)
默认交换机(Default Exchange)
RabbitMQ 预置了一个没有名称的默认交换机(""),类型为 direct。它的特殊之处在于会自动将队列名称作为路由键。也就是说,无需显式绑定,发送消息时直接使用队列名称作为路由键即可将消息发往该队列。
- 快速开始,无需创建交换机和绑定。
- 适用于简单的点到点通信。
# 创建一个队列,不声明交换机
queue_name = 'hello'
channel.queue_declare(queue=queue_name)
# 发送消息给默认交换机,路由键就是队列名
channel.basic_publish(exchange='', routing_key=queue_name, body='Hello')