一、整体流程设计
消息队列系统的基本流程如下:
Producer --> Broker --> Consumer
- Producer:发送消息至 Broker;
- Broker:负责接收、存储消息,并将消息转发给 Consumer;
- Consumer:消费消息并确认;
- ACK机制:Consumer 消费成功后需回执,Broker 才标记该消息为“已处理”。
二、RPC 通信机制设计
系统中至少涉及两次 RPC 通信:
- Producer → Broker
- Broker → Consumer
为保障性能与扩展性,可以借鉴 Dubbo 等成熟 RPC 框架的设计思路:
- 服务注册与发现:采用 Consul/ZooKeeper/Nacos;
- 通信协议:可自定义高性能二进制协议(类似 Dubbo 协议);
- 序列化协议:支持 ProtoBuf、Hessian、JSON 等多种格式;
- 连接池管理:保持长连接 + 异步处理 + 超时控制。
三、消息持久化与堆积处理
1. 持久化策略
- 采用文件系统(顺序写),可提高写入效率;
- 类似 Kafka,日志文件命名按 topic + partition;
- 定期压缩 + 文件归档 + 删除旧数据。
2. 消息堆积应对方案
- 按 partition 分区并并发消费;
- 动态扩展 partition 数量;
- 将堆积消息转移至临时 topic + 临时 consumer 加速处理;
- 支持过期消息自动丢弃或转存到死信队列(DLQ)。
四、消费关系管理
1. 消费模型
- 点对点(Queue):一个消息只能被一个 consumer 消费;
- 发布/订阅(Topic):一个消息可被多个 consumer 组消费。
2. 消费进度维护
- 每个 consumer group 维护独立的 offset;
- offset 存储在:
- 本地磁盘
- Broker 内部元数据
- ZooKeeper / Redis / Config Server
五、消息可靠性设计
1. 消息丢失防止
- Producer:发送消息需开启 ACK 机制;
- Broker:使用 WAL(Write-Ahead Logging)+ 多副本;
- Consumer:消息消费需回执确认;
2. 幂等性处理
- 消息引入唯一 ID(如 UUID);
- 消费侧维护 消费日志表 / Redis Set 防止重复处理;
- 业务逻辑必须天然支持幂等。
六、高可用机制设计
借鉴 Kafka 的 HA 机制:
- Broker 多副本架构:
- 每个 partition 对应多个副本;
- 一个为 leader,其余为 follower;
- Leader 选举机制:
- leader 崩溃时,自动选举新的 leader;
- ZooKeeper / Raft 协议:
- 保证集群状态一致性;
- 支持 Broker 热升级与自动故障转移。
七、消息事务机制设计
保障“本地操作成功 → MQ 发送成功”的事务一致性:
- 本地业务操作与消息记录写入同一事务;
- 采用“消息落库 + 补偿机制”:
- 业务操作后将消息持久化到本地消息表;
- 独立任务扫描未投递消息并发送到 MQ;
- MQ ACK 后标记为“已投递”。
八、扩展性与吞吐设计
参考 Kafka 架构的可扩展性思路:
- 层级结构:Broker -> Topic -> Partition;
- 每个 Partition 可分配到不同 Broker;
- 增加 Partition + 扩展机器 → 提高吞吐;
- 支持水平扩展 Broker 和 Consumer 节点。