direct交换器是rabbitmq中基于routing_key与binding_key严格全等匹配的消息过滤路由方案,大小写敏感、空格计入比较,要求发布时非空key、绑定时非空binding_key,且二者必须完全一致才能投递。

Direct exchange 是消息过滤路由的最小可行解
Go 用 RabbitMQ 做消息过滤,fanout 只能广播,真要按 severity、type、tenant_id 这类字段分流,必须切到 direct 类型交换器。它不搞模糊匹配,只做字符串全等比对——简单、可控、没歧义。
-
direct的路由逻辑只看routing_key和binding_key是否完全一致,大小写敏感,空格算字符 - 发送端调用
ch.Publish()时必须显式传入非空routing_key,否则会被丢弃(fanout下空 key 没问题,这里不行) - 一个队列可绑定多个
binding_key(比如同时绑"error"和"critical"),但一个binding_key也可被多个队列共用——这是实现“多消费者订阅同一事件”的基础 - 如果发了一个没人 bind 的
routing_key(比如发了"warn"但所有队列只绑了"error"),消息直接进黑洞,AMQP 协议不报错也不回执
QueueBind 的 binding_key 参数不能省,也不能传空字符串
很多人照抄 fanout 示例,把 QueueBind 第二个参数写成 "",结果消息永远收不到——因为 direct 会严格校验,空字符串和任何非空 routing_key 都不匹配。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 正确写法:
ch.QueueBind(q.Name, "error", "logs_ex", false, nil) - 错误写法:
ch.QueueBind(q.Name, "", "logs_ex", false, nil)(队列对所有 key 都不感兴趣) - binding_key 是队列声明时“订阅条件”,不是队列名字;同一个队列可多次调用
QueueBind绑不同 key,无需删队列重来 - 注意:exchange 名称(第三个参数)必须和
Publish时用的一致,大小写、下划线都不能错,RabbitMQ 不自动创建 exchange
Go 客户端里 routing_key 和 binding_key 的角色别搞反
新手常混淆谁该填什么——简单记:发送方决定 routing_key(相当于消息打的标签),接收方在 QueueBind 时填 binding_key(相当于队列设的过滤器)。两者对齐才通路。
- 发消息:
ch.Publish("logs_ex", "error", false, false, amqp.Publishing{Body: []byte("disk full")})→ 这里的"error"是routing_key - 绑队列:
ch.QueueBind("err_log_q", "error", "logs_ex", false, nil)→ 这里的"error"是binding_key - 如果发的是
"warning",但队列只绑了"error",消息就静默丢失;没有 fallback 机制,也不会进死信队列(除非你额外配置) - 调试时用
rabbitmqctl list_bindings看实际绑定关系,比查代码更可靠
不要在 Go 层做字符串解析替代 binding_key
有人想“灵活点”,发消息时塞 JSON 到 body,然后在消费者里 json.Unmarshal 再 if-else 分流——这等于放弃 RabbitMQ 的路由能力,把压力和逻辑全推到 Go 进程里,还丧失了天然的水平扩展性。
- binding_key 应该是业务语义明确的短标识,如
"user.created"、"payment.failed",而非动态生成的 ID 或时间戳 - 如果真需要多维过滤(比如既要 type 又要 region),要么用
topicexchange + 多段 key(如"user.us.created"),要么前置用另一个服务做规则引擎投递到不同 direct exchange - Go 侧只负责“收指定 key 的消息”,过滤逻辑越薄越好;加日志、埋点、重试这些可以,但别在里面写 switch 匹配 message.Header
fmt.Printf 打印 key,也别靠猜。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










