RabbitMQ 头交换机

头交换机(Headers Exchange)是四种内置交换机中最特殊的一种:它不按 routing key 路由,而是按消息 headers 属性中的键值对去匹配队列绑定时声明的条件,适合"多条件组合路由",但使用率很低。

头交换机原理

其它交换机路由只看 routing key,headers 交换机则把判断依据移到消息头上:每个队列绑定可声明一组键值条件(写在绑定的 arguments 里),消息到达时 broker 取出消息 headers 与各绑定条件比对,命中才投递到对应队列。

条件含义效果
x-match=all全部键值都命中相当于 AND,最常用
x-match=any命中任一键值即可相当于 OR

x-match 必须显式写在绑定的 arguments 中;消息头上多带多少额外键都不影响匹配结果。

声明与绑定

先声明类型为 headers 的交换机,再为每个队列做一次带条件的绑定:

# 声明 headers 交换机与队列
rabbitmqadmin declare exchange name=hd.ex type=headers durable=true
rabbitmqadmin declare queue name=q.audit durable=true
# 绑定:type=audit 且 app=pay 全部命中才投递到 q.audit
rabbitmqadmin declare binding source=hd.ex destination=q.audit routing_key="" \
    arguments='{"x-match":"all","type":"audit","app":"pay"}'

注意:绑定到 headers 交换机时 routing_key 会被忽略,即使填了也不参与判断。

发送带 headers 的消息

生产者把匹配条件放进消息的 headers 属性,routing key 传空即可:

import pika
conn = pika.BlockingConnection(pika.ConnectionParameters("127.0.0.1"))
ch = conn.channel()
# 消息头声明审计类型与来源应用(多带的 env 键不影响匹配)
props = pika.BasicProperties(headers={"type": "audit", "app": "pay", "env": "prod"})
ch.basic_publish(exchange="hd.ex", routing_key="", body=b"pay audit log", properties=props)
print("headers 消息已发送")  # 输出:headers 消息已发送
conn.close()

上面的消息因 type、app 两项都命中绑定条件而被投递到 q.audit;若把条件改为 x-match=any,则只满足其中一项也会投递。

与其它交换机对比

交换机路由依据典型用途使用频率
directrouting key 完全相等按级别/事件精确分发
fanout广播,不判断日志、公告扇出
topicrouting key 通配符匹配按主题订阅
headers消息头键值组合多属性 AND/OR 条件很低

headers 能表达"属性组合"条件,这是 topic/direct 做起来别扭的地方;但代价是多一层封装、排查麻烦,绝大多数需求用 direct 或 topic 就能覆盖。

适用场景与注意点

头交换机适合属性维度多、且需要任意组合匹配的少数场景(如按终端类型+客户端版本+地区组合做灰度)。使用时注意三点:绑定条件必须带 x-match;消息必须通过 headers 属性携带匹配键,靠 routing key 发不进来;条件值类型要一致,字符串 "1" 与整数 1 视为不同值,不会互相匹配。

小结

头交换机按消息头键值对与绑定条件匹配路由,x-match=all 表示全命中、x-match=any 表示任一命中。它组合表达能力强但使用率最低,能用 direct/topic 表达的场景优先用它们。

笔记加载中…