NOTE
1.1 消息队列介绍
1. 什么是MQ - 消息队列,解耦生产者和消费者 - 生产者消费者其实也可以用数据库实现:生产者可以将事件写入数据库,消费者定时轮询数据库 - 但是这种方式对数据库的压力太大 2. MQ消息分发模型 - 有两种消息模型:队列模型和发布-订阅模型 2.1. 队列模型 - 一个生产者- Queue-
这是历史学习笔记,可能存在过时或不完整的理解。
1. 什么是MQ
- 消息队列,解耦生产者和消费者
- 生产者消费者其实也可以用数据库实现:生产者可以将事件写入数据库,消费者定时轮询数据库
- 但是这种方式对数据库的压力太大
2. MQ消息分发模型
- 有两种消息模型:队列模型和发布-订阅模型
2.1. 队列模型
- 一个生产者->Queue->一个消费者
- 一个生产者生产的消息由一个消费者独立消费;如果有多个消费者同时消费这个Queue,那么Queue的数据会分散给这几个消费者
- 那我想多个消费者都独立的消费Queue的完整数据怎么办?只能建立多个Queue,每个Queue对应一个消费者

2.2. 发布订阅模型
- 一个生产者->Topic->多个消费者
- 一个生产者产生的消息能够被多个消费者同时独立消费。
- 如果只有一个消费者,那么就是队列模型

3. 消息推送模式
3.1. Push
- 由服务器主动推送消息给客户端
- 优点
- 实时性好
- 缺点
- 客户端无法根据自己的能力决定消费速率
- 需要服务器保持长连接以防消息丢失
3.2. Pull
- 由客户端从服务器拉取消息
- 优点
- 客户端可以根据自己的能力决定消费速率
- 缺点
- 需要轮询对服务器压力大
- 实时性差了点
4. 使用MQ的好处
4.1. 解耦
- 没有解耦的时候,系统A需要直接调用其他系统的接口发送数据,每增加/删除一个消费方系统A都需要改代码。
- 解耦后,系统A只需要发送数据到MQ中,其他系统可以从MQ中消费数据

4.2. 异步
- 同步调用的场景,系统A需要调用系统B、C、D,每个耗时200ms,那么总共耗时600ms
- 使用了mq异步化可以更快速的响应用户请求,系统A只需要写入MQ,耗时100ms,其他系统自己消费进行处理

4.3. 削锋
- 高峰时期5K个请求直接打在数据库上,崩溃
- 使用mq抗住写请求,消费者根据能力进行处理

5. 使用MQ的坏处
5.1. 可用性问题
- MQ挂了,整个系统就崩溃了
- 如何解决
- 开启集群模式
5.2. 消息丢失问题
- 消费者没有消费到生产者发送的消息有三方面原因:一个是生产者发送失败,一个是MQ把消息丢了,一个是消费者没消费成功,却直接报告给MQ成功了
- 如何解决
- 生产者
- 重试或者利用分布式事务方案之可靠消息最终一致性.md
- MQ
- 消费者
- 关闭自动提交,使用手动提交
- 生产者
5.3. 幂等性问题
5.3.1. 生产者重复发送
生产者重复发送问题不大,主要是保证消费者不重复消费即可
5.3.2. 消费者重复消费
- 消费者消费后没有commit offset(比如程序崩溃/强行kill/消费耗时/自动提交偏移情况下unscrible)
- 如何解决
- 这个属于消费者自己的问题不是MQ的问题,需要消费者自行解决
- 编写幂等消息处理程序。写数据库的话可以先用主键查一下,有则不要插入
- 跟踪消息并处理重复项。比如在数据库中记录message id 来去重,可以使用redis的set保存处理过的数据的key
5.4. 顺序性问题
5.5. 一致性问题
- ABC写入成功才算成功,但是C失败了,那么就会造成数据不一致的现象
- 如何解决
- 手动确认+重试
6. 如何实现MQ
- 可以使用日志系统实现消息的持久化
- 生产者将消息追加到日志的末尾,而消费者通过依次读取日志来接收消息
- 为了保证高性能可以对日志分区,每个分区放到不同的节点上
- 为了保证高可用可以对日志复制,每个副本放到不同的节点上
- 在每个分区之中,每个消息都会有一个单调递增的序列号,这样能够保证分区之中所有的消息是完全有序的,而不同分区之间的消息则没有顺序保证
7. 常见的MQ
7.1. RabbitMQ
7.2. Kafka
7.3. MQ选型
2026 注:下面的选型表是当时的粗略经验值;QPS、社区活跃度和可靠性能力都会随版本、配置与部署方式变化,不应作为固定基准。
| ActiveMQ | RabbitMQ | RocketMQ | Kafka | |
|---|---|---|---|---|
| 功能 | 不完备,可能丢失消息 | 完备(消息可以各种路由) | 完备 | 不完备(普通的收发消息),可能丢失消息 |
| QPS | 万级并发 | 万级并发 | 十万级并发 | 十万级并发 |
| 社区活跃 | 不活跃 | 活跃 | 活跃 | 活跃 |
| 语言 | Java | erlang | Java | Java |