RabbitMQ 的核心是 Exchange(交换机),它决定消息如何路由到队列。RabbitMQ 内置四种交换机类型,每种适用于不同业务场景。


一、四种交换机的核心区别(总览表)

交换机类型 路由规则 是否使用 routing_key 典型场景 特点
Direct 精确匹配 routing_key 订单状态、日志级别分类 简单、精准
Fanout 广播到所有绑定队列 广播消息、缓存更新 不看 routing_key
Topic 通配符匹配 routing_key 是(支持 * 和 #) 复杂路由、日志系统 最灵活
Headers 根据消息头匹配 否(看 headers) 元数据路由、协议类消息 使用较少

二、Direct Exchange(直连交换机)

路由规则

routing_key 完全匹配 才会投递。

例如:

  • 队列 A 绑定 routing_key = order.create
  • 队列 B 绑定 routing_key = order.cancel

消息 routing_key = order.create → 只进入队列 A。

Python 示例

channel.exchange_declare(exchange='direct_ex', exchange_type='direct')

channel.queue_declare(queue='order_create')
channel.queue_bind(exchange='direct_ex', queue='order_create', routing_key='order.create')

channel.basic_publish(
    exchange='direct_ex',
    routing_key='order.create',
    body='创建订单'
)

适用场景

  • 订单状态变更
  • 日志级别(info / warn / error)
  • 精准路由的业务场景

三、Fanout Exchange(扇形交换机)

路由规则

广播模式:消息会发送到所有绑定队列,忽略 routing_key。

Python 示例

channel.exchange_declare(exchange='fanout_ex', exchange_type='fanout')

channel.queue_declare(queue='q1')
channel.queue_declare(queue='q2')

channel.queue_bind(exchange='fanout_ex', queue='q1')
channel.queue_bind(exchange='fanout_ex', queue='q2')

channel.basic_publish(
    exchange='fanout_ex',
    routing_key='',
    body='系统广播消息'
)

适用场景

  • 广播通知
  • 缓存更新
  • 多服务同步消息

四、Topic Exchange(主题交换机)

路由规则

支持通配符:

  • * 匹配一个单词
  • # 匹配多个单词

例如:

  • 队列 A 绑定:log.*
  • 队列 B 绑定:log.#

消息 routing_key:

  • log.info → A、B 都能收到
  • log.info.user → 只有 B 收到

Python 示例

channel.exchange_declare(exchange='topic_ex', exchange_type='topic')

channel.queue_declare(queue='q_info')
channel.queue_declare(queue='q_all')

channel.queue_bind(exchange='topic_ex', queue='q_info', routing_key='log.*')
channel.queue_bind(exchange='topic_ex', queue='q_all', routing_key='log.#')

channel.basic_publish(
    exchange='topic_ex',
    routing_key='log.info.user',
    body='用户日志'
)

适用场景

  • 日志系统(log.info.user)
  • 多级分类路由
  • 微服务事件总线

五、Headers Exchange(头交换机)

路由规则

根据消息头(headers)匹配,而不是 routing_key。

支持两种匹配模式:

  • x-match = all(全部匹配)
  • x-match = any(任意匹配)

Python 示例

channel.exchange_declare(exchange='headers_ex', exchange_type='headers')

args = {
    'x-match': 'all',
    'type': 'pdf',
    'format': 'A4'
}

channel.queue_declare(queue='q_pdf')
channel.queue_bind(exchange='headers_ex', queue='q_pdf', arguments=args)

channel.basic_publish(
    exchange='headers_ex',
    routing_key='',
    body='PDF 文档',
    properties=pika.BasicProperties(headers={'type': 'pdf', 'format': 'A4'})
)

适用场景

  • 协议类消息(根据 metadata 路由)
  • routing_key 不够表达业务含义的场景

六、四种交换机的 Python 对比示例(最简模板)

channel.exchange_declare('ex_direct', 'direct')
channel.exchange_declare('ex_fanout', 'fanout')
channel.exchange_declare('ex_topic', 'topic')
channel.exchange_declare('ex_headers', 'headers')

七、如何选择交换机?(实战建议)

  • 需要精准路由 → Direct
  • 需要广播 → Fanout
  • 需要复杂路由 → Topic
  • 需要根据消息属性路由 → Headers
  • 需要延时队列 → x-delayed-message(插件)
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐