RabbitMQ 主题交换机

topic(主题)交换机按"模式匹配"路由:binding key 里允许通配符,把一个模式对应的整类 routing key 收进来,是三种常用交换机中最灵活的。

路由语义与通配符

topic 通配符匹配 routing key 用点 . 分隔成若干"词"(word),binding key 中可用两个通配符:

通配符含义示例 binding key
*恰好匹配一个词log.*.error
#匹配零个或多个词log.#

没有通配符的词按字面精确匹配(同 direct)。消息会复制给所有匹配成功的绑定队列;topic 的 routing key 整条最长 255 字节,超出会发布失败。

通配符匹配示例

假设发布三类消息:user.created、user.updated、user.order.paid,各 binding key 的命中结果如下:

binding keyuser.createduser.updateduser.order.paid
user.*命中命中不命中(三段 key,* 只占一段)
user.#命中命中命中
*.created命中不命中不命中
#.paid不命中不命中命中
#命中命中命中

典型写法:用户事件分流

用户服务发两类事件,一个队列只要"创建",另一个队列全要:

import pika
conn = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
ch = conn.channel()
ch.exchange_declare(exchange='user.topic', exchange_type='topic', durable=True)
ch.queue_declare(queue='user.created.q', durable=True)
ch.queue_declare(queue='user.all.q', durable=True)
ch.queue_bind(queue='user.created.q', exchange='user.topic', routing_key='user.created')
ch.queue_bind(queue='user.all.q', exchange='user.topic', routing_key='user.#')
ch.basic_publish(exchange='user.topic', routing_key='user.created', body=b'u100 created')
ch.basic_publish(exchange='user.topic', routing_key='user.updated', body=b'u100 updated')
# 输出:user.created 只进 user.created.q;两条消息都进 user.all.q
conn.close()

典型写法:两级日志键

日志用"系统.级别"做 routing key,一个 binding 就能收所有系统的 error:

facility.severity 两级键示例:
binding "*.error"   ← 收所有系统的 error(web.error、pay.error、task.error ...)
binding "pay.*"     ← 只收支付系统所有级别
binding "#"         ← 全收(调试用,慎用)

# 与 * 辨析

    • 只代表"一个词":user.* 收 user.created,收不了 user.created.v1;
  • 代表"任意多个词(含 0 个)":user.# 能收 user.created,也能收 user.created.v1,连单词 user 本身也收;

  • 两者可混用:*.log.# 表示"第一段任意、之后以 log 开头再接任意内容"。

注意事项

  • 发布到 topic 交换机的消息,routing key 不能为空:空 key 的消息无法匹配,会被直接丢弃;
  • 通配符只在 binding key 里有特殊含义:生产者在 routing key 里写 * 或 # 会被当成普通字符处理,属于反模式,应使用明确的事件键;
  • 通配符按"词"整段生效,不能嵌在词里做字符级模糊:* 与 # 必须各自独占一个词,例如 binding key 写成 u*.created,其中的 * 不被识别为通配、只会按字面字符匹配,几乎永远命中不了;需要"任意用户"应把键设计成 *.created 这类整段通配,或让生产者统一键格式。

小结

topic 交换机用 * 和 # 按段匹配 routing key,一个绑定收一类消息,是 direct 的"模糊升级版"(不含通配符时行为与 direct 相同)。至此三类常用交换机讲完,下一章 headers 交换机用消息头做多条件匹配,适用于更复杂的组合条件。

笔记加载中…