
消息队列选型的主要成本不在中间件本身,而在耦合:业务代码中散落的发送方、消费方与序列化逻辑一旦绑定特定客户端 SDK,更换队列就意味着大规模重构。
DC3 的答案是把消息总线做成可替换层:dc3-mq/ 家族里,dc3-mq-core 定义端口与消息语义,六个适配器各自对接一个消息队列------RabbitMQ(默认)、Kafka、Pulsar、MQTT、ActiveMQ、RocketMQ。数据中心等业务方只依赖 core 的接口,不感知底层是哪家。

关键不是适配器数量,是 TCK
实现多个适配器并不困难,真正的挑战在于:如何证明六个适配器的行为一致?
DC3 的做法是从数据库家族借来的:TCK(Technology Compatibility Kit)契约测试套件。一套与实现无关的测试用例,定义了消息总线必须满足的全部契约------发送、消费、确认语义、异常行为------六个适配器分别跑同一套 TCK,全部通过才算合格。
这带来两个实际好处:
- 换型可信。从 RabbitMQ 切到 Kafka,不是"理论上应该能跑",而是同一套契约验证过的等价行为;
- 新增适配器有据可依:实现 core 接口并跑通 TCK,即为完整的验收标准。
什么场景选什么队列

六种队列各有适用场景,官方文档 docs/mq-brokers.md 有完整的选型指南,粗略概括:
- RabbitMQ(默认):中等规模、路由灵活、开箱即用,绝大多数部署从它开始;
- Kafka:高吞吐、需要回放与多消费者扇出的数据管道场景;
- Pulsar:存算分离、多租户队列需求突出的场景;
- MQTT:边缘侧已经有 MQTT broker(如 EMQX)的基础设施复用;
- ActiveMQ / RocketMQ:存量中间件资产与国产化技术栈的适配。
换型在部署侧完成:启动目标消息队列容器、修改环境变量、更换数据中心依赖打包,业务代码零改动。
实事求是的边界
- 抽象层只覆盖各队列的公共语义子集。Kafka 的消费组精细控制、RabbitMQ 的死信路由等高级特性不经 core 暴露,需要时应直接使用对应队列的原生客户端;
- 默认适配器(RabbitMQ)随服务打包,其余按部署显式引入,避免不必要的依赖开销。
仓库 :GitHub
pnoker/iot-dc3· Giteepnoker/iot-dc3(GVP)文档:docs.dc3.site · 选型指南 docs/mq-brokers.md · book.dc3.site · demo.dc3.site