系列导航:

到这一步,确认、顺序和积压的边界已经清楚了。接下来最常见的错误不是参数没调好,而是模式一开始就选错了。下面统一用订单域做例子:订单服务会发布 order.created,库存、通知、对账等下游围绕它消费;只有讲到 RPC 时,会故意把它当作反例,因为 RPC 本质上不是事件广播。

共享示例:order.created

{
  "eventId": "01JABCXYZ9Q4T2R8M7N6P5K4H3",
  "eventType": "order.created",
  "occurredAt": "2026-08-05T10:00:00Z",
  "orderId": "ORD-20260805-001",
  "customerId": "C10086",
  "amount": 299.00
}

选模式时,先别问“该用哪个 Exchange”,而要先问“我要解决的业务问题是什么”。同样是 RabbitMQ,不同模式背后的意图完全不同。

五种消息模式的投递语义五张对照卡片分别展示单一队列、竞争消费、发布订阅、路由过滤和 RPC 请求响应的投递路径。01 · SIMPLE QUEUESimple QueueProducerQueueCon-sumer一个工作 → 一个主消费方单一工作管道02 · COMPETEWork QueueProducerQueueWorker AWorker B多个 Worker 竞争仅一个 Consumer 收到03 · COPYPub/SubPExchangeQueueQueueINInventory / Notification每个订阅者各有一份04 · FILTERRouting / Topicorder.createdExchangeorder.* bindingorder.cancelledrouting key 过滤未匹配事件被拒绝05 · REQUEST / RESPONSERPCRequesterRPC QueueResponderReply Queuereply-to · correlationId响应沿箭头回到 Requester五种消息模式的投递语义五张纵向卡片依次展示 Simple Queue、Work Queue、发布订阅、Topic 路由和 RPC 的消息路线。01 · SIMPLE QUEUESimple QueueProducerQueueConsumer单一工作管道02 · COMPETEWork QueueProducerQueueWorker AWorker B仅一个 Consumer 收到03 · COPYPub/SubPExchangeQueueQueueInvNote每个订阅者各有一份04 · FILTERRouting / Topicorder.createdExchangeorder.*order.cancelledrouting key 过滤05 · REQUEST / RESPONSERPCRequesterRPC QueueResponderReply Queuereply-to · correlationId
五种消息模式的投递语义先按业务意图选投递语义,再决定 Exchange、Queue 和路由键的具体组合。
同一个业务事件在 Simple Queue、Work Queue、发布订阅、Topic 路由和 RPC 中会分别形成单一工作管道、竞争消费、独立副本、规则过滤和请求响应回路。

Simple Queue

  1. 解决什么业务问题:一个生产者把工作交给一个下游顺序处理,重点是“先把事情排队做完”,例如订单服务把 order.created 交给一个审计归档程序写入历史库。
  2. 在 RabbitMQ 里通常长什么样:一个生产者、一个 Queue、一个主要消费方;即使后面暂时只部署一个 Consumer 实例,本质上也是“一条工作管道”。
  3. 最常见误区是什么:把 Simple Queue 误解成“天然严格顺序且绝不重复”;实际上失败重投递、消费者重启和业务耗时差异,都会让你看到的处理结果不再像想象中那样线性。

Work Queue

  1. 解决什么业务问题:同一种任务很多,想让多个 Worker 分摊压力,例如订单创建后要生成电子发票或履约单,这类任务可以由多个实例并行处理。
  2. 在 RabbitMQ 里通常长什么样:多个 Consumer 竞争同一个 Queue,谁空闲谁拿下一条消息;消息不是“广播给每个 Worker”,而是“分给某一个 Worker”。
  3. 最常见误区是什么:以为增加两个 Worker 就等于每条消息会被处理两次;实际上 Work Queue 的目标是分摊,不是复制,多个消费者消费同一队列时拿到的是不同消息。

Pub/Sub

  1. 解决什么业务问题:同一个业务事件发生后,希望多个下游都各自收到一份,例如 order.created 同时触发库存预留、用户通知和数据分析。
  2. 在 RabbitMQ 里通常长什么样:生产者把消息发到一个 Exchange,每个订阅方有自己的独立 Queue;消息会被复制到多个队列,而不是让多个服务去抢同一个队列。
  3. 最常见误区是什么:把“多个服务消费同一个 Queue”当成订阅发布;那其实是竞争消费,最终每条消息只会落到其中一个消费者手里。

Routing / Topic

  1. 解决什么业务问题:消息不是所有人都要,而是只让关心某类事件的下游收到,例如订单域既有 order.created 也有 order.cancelled,不同系统只订阅自己关心的那部分。
  2. 在 RabbitMQ 里通常长什么样:生产者仍然先发到 Exchange,但订阅方通过 Routing Key 或通配规则把消息筛到各自队列里,例如只收 order.created,或收一组 order.* 事件。
  3. 最常见误区是什么:把 Routing Key 当成“队列名字”或“万能业务分类系统”;它真正承担的是路由条件,不替你设计完整的事件模型,也不会自动修正混乱的命名体系。

RPC

  1. 解决什么业务问题:调用方必须马上拿到一个结果,才能继续当前请求链路,例如提交订单前要同步拿到风控分数或运费试算结果。
  2. 在 RabbitMQ 里通常长什么样:请求方发送请求消息,并带上 reply-tocorrelationId,服务端处理后再把响应发回指定回复队列,本质上仍是“消息化的请求-响应”。
  3. 最常见误区是什么:把已经发生的 order.created 事件也硬做成 RPC,边发消息边等别人回结果;一旦你必须等待结果才能继续,那通常说明这一步本来就不是事件广播,而是同步调用需求。

本篇解决了什么:

  • 把 Simple Queue、Work Queue、Pub/Sub、Routing/Topic 和 RPC 放回“要解决什么业务问题”里理解,而不是只背 RabbitMQ 术语。
  • 澄清了几类常见误解:竞争消费不等于广播,Routing Key 不等于业务模型,RPC 也不等于事件驱动。

下一篇:RabbitMQ + .NET 实战:建立连接、声明拓扑与发布消息(七)