首页 / 知识库 / python服务端进阶 / 消息队列入门

02 - 核心概念与工作模型

上一章我们用”餐厅挂单栏”建立了直觉。这一章把这套模型正式拆开,认识几个所有消息队列都通用的核心角色。搞懂了它们,你换到任何 MQ 框架都能秒懂。


2.1 四个核心角色

┌──────────┐      ┌──────────────────────────┐      ┌──────────┐
│ 生产者    │─────▶│         Broker            │─────▶│ 消费者    │
│ Producer │ 发消息│  ┌────────────────────┐   │ 取消息│ Consumer │
│          │      │  │   队列 Queue        │   │      │          │
│(FastAPI) │      │  │  [msg][msg][msg]... │   │      │(后台worker)│
└──────────┘      │  └────────────────────┘   │      └──────────┘
                  │     (消息在这里排队暂存)     │
                  └──────────────────────────┘
角色对应餐厅职责
生产者 Producer点单的服务员产生消息、把消息发给 Broker。通常就是你的 FastAPI 接口
消费者 Consumer后厨的厨师从 Broker 取出消息并处理。通常是独立运行的后台 worker
Broker(消息中间件)挂单栏所在的整个后厨系统独立运行的服务,负责接收、暂存、投递消息。RabbitMQ / Kafka 等就是 Broker
消息 Message一张小票被传递的数据本身,比如 {"event": "user_registered", "user_id": 1001}

关键认知:Broker 是一个独立的服务进程,通常单独部署(甚至单独一台机器 / 一个 Docker 容器)。你的 FastAPI 应用和后台 worker 都通过网络连接到它。它们三者是分开的。


2.2 消息的一生:从产生到被处理

一条消息完整走一遍,是这样的:

① 生产者创建消息
   {"event": "user_registered", "user_id": 1001}

        ▼  通过网络发送
② Broker 收下消息,放进队列排队
   队列: [msg3][msg2][msg1] ← 新消息进这头


③ 消费者向 Broker 说"给我来一条"


④ Broker 把队头的消息投递给消费者


⑤ 消费者处理消息(发邮件 / 写库 / ...)


⑥ 处理成功后,消费者告诉 Broker:"这条我搞定了"(确认 ACK)


⑦ Broker 收到确认,把这条消息从队列里删掉

其中第 ⑥ 步的确认机制(ACK)非常关键,它是消息队列”不丢消息”的核心保障——如果消费者处理到一半崩了、没发确认,Broker 会认为这条消息没处理成功,之后会重新投递给别的消费者。我们在 第 07 章 会专门讲。

现在你只要记住一句话:消息不是”发出去就删”,而是”确认处理成功后才删”。 这就是它比”直接调用”更可靠的原因。


2.3 两种最基本的消息模型

不同场景下,“消息该发给谁”是不一样的。这引出两种最经典的模型。

模型一:点对点(一条消息只被一个消费者处理)

一个队列,多个消费者抢着消费,但每条消息只会被其中一个消费者拿到。适合”任务分发”:比如 100 个发邮件任务,交给 3 个 worker 分摊干活。

                       ┌──────────┐
                  ┌───▶│ 消费者 A  │  处理 msg1、msg4 …
┌──────────┐     │    └──────────┘
│  队列      │────┤    ┌──────────┐
│[m4][m3][m2]│    ├───▶│ 消费者 B  │  处理 msg2、msg5 …
│[m1]        │    │    └──────────┘
└──────────┘     │    ┌──────────┐
                  └───▶│ 消费者 C  │  处理 msg3、msg6 …
                       └──────────┘

一条消息只发给 A / B / C 中的一个 → 多个 worker 分摊工作(负载均衡)

好处:加机器就能提速。任务处理不过来?多起几个消费者进程就行,它们会自动分摊队列里的消息。

模型二:发布/订阅(一条消息被所有订阅者各收一份)

一条消息,每个关心它的消费者都能收到一份自己的副本。适合”一个事件,多方响应”:比如”用户已注册”这个事件,邮件服务、短信服务、推荐系统都想知道。

                    ┌────────────┐
              ┌────▶│ 邮件服务    │ 收到一份"用户已注册"
┌──────────┐ │     └────────────┘
│ "用户已注册"│─┼────▶┌────────────┐
│  事件      │ │     │ 短信服务    │ 收到一份"用户已注册"
└──────────┘ │     └────────────┘
              └────▶┌────────────┐
                    │ 推荐系统    │ 收到一份"用户已注册"
                    └────────────┘

同一条消息,每个订阅者各拿一份 → 一次广播,多方响应

RabbitMQ 通过一个叫交换机(Exchange)的部件来实现这两种模型的灵活切换,这是它设计上最有特色的地方,第 05 章 细讲。你现在只要理解这两种模型的区别:一条消息是”被抢走一次”,还是”人手一份”。


2.4 为什么要有 Broker 这个”中间人”?

你可能会想:生产者直接调用消费者不行吗?为什么非要中间夹一个 Broker?

因为有了这个中间人,生产者和消费者就实现了”三个不用”:

┌──────────┐          ┌──────────┐          ┌──────────┐
│ 生产者    │  ──X──▶  │  Broker  │  ──X──▶  │ 消费者    │
└──────────┘          └──────────┘          └──────────┘

  ① 不用同时在线:消费者哪怕暂时挂了,消息也在 Broker 里存着,等它恢复再处理
  ② 不用互相认识:生产者只管发给 Broker,根本不需要知道有几个消费者、它们在哪
  ③ 不用同步等待:生产者发完就走,不用站着等消费者处理完

这”三个不用”,正是 第 03 章 里”解耦 / 异步 / 削峰”的底层原理。


本章小结

知识点要点
四个角色生产者、消费者、Broker(中间件)、消息
Broker 是什么独立运行的服务,负责接收、暂存、投递消息
消息的一生产生 → 入队 → 投递 → 处理 → 确认 ACK → 删除
ACK 的意义消息”确认成功后才删”,处理失败会重投,这是不丢消息的关键
两种模型点对点(一条消息一个消费者,用于任务分摊)/ 发布订阅(一条消息人手一份,用于事件广播)
为什么要 Broker让收发双方”不用同时在线、不用互相认识、不用同步等待”

下一章预告:把这些概念串成价值——消息队列到底怎么实现解耦、异步、削峰这三大目标。


上一章 ← 01 - 为什么需要消息队列 | 下一章 → 03 - 解决的三大问题