什么是消息队列
消息队列是一种基于 “生产者-消费者” 模式的中间件,核心作用是在不同系统或组件间暂存、传递消息,实现异步通信和解耦,避免因系统间直接调用导致的依赖和性能问题。
消息队列怎么选型
| 特性 | RabbitMQ | RocketMQ | Kafka |
|---|---|---|---|
| 单机吞吐量 | 万级 | 10 万级 | 10 万级 |
| 时效性 | 微秒级 | 毫秒级 | 毫秒级 |
| 可用性 | 高(主从) | 非常高(分布式) | 非常高(分布式) |
| 消息重复 | 至少一次 | 一次 | 一次 |
| 消息顺序性 | 有序 | 有序 | 分区有序 |
| 支持主题数 | 百万级 | 千级 | 百级 |
| 消息回溯 | 不支持 | 支持 | 支持 |
- 对于秒杀活动,应当选择Kafka或RocketMQ这类高吞吐量的
- 对于金融业务,应重点考虑稳定性、安全性,分布式部署的Kafka和RocketMQ比较适合
- 对于公司中台,对外提供服务,需要较多的主题接入,考虑RocketMQ或者RabbitMQ
消息队列的使用场景有哪些
- 解耦:在多个系统之间解耦,将原本通过网络之间的调用方式改为使用mq进行异步通信,只要该操作不需要同步,就可以改为MQ进行多个系统之间的联系,这样项目之间不会存在耦合,就算一个系统挂了,也只是消息积压在mq里没人处理,不会对其他系统造成影响
- 异步:主流程发完消息即返回,用户无需等待非核心步骤,大幅降低感知延迟,提升体验
- 削峰:将用户的消息放到mq里,系统按自己最大的消费能力去消费这些消息,保证系统的稳定
如何解决消息重复消费问题
首先要明确,MQ 无法彻底杜绝消息重复,因为网络波动、集群主从切换等不可抗因素,消息重复是必然会发生的。所以解决思路不是‘避免重复’,而是‘让重复消息不影响业务正确性’,也就是实现消费端的幂等性处理
主要有三种常用方案:
- 基于消息唯一ID去重:生产者发送消息时,给每个消息带一个全局唯一 ID,消费者拿到消息后,先去 Redis 或数据库的‘已消费消息表’查这个 ID 是否存在。如果不存在,就处理业务,同时把 ID 存进去;如果存在,直接跳过。
- 基于业务唯一键去重:如果业务本身就有天然的唯一标识,不用额外生成消息ID。比如扣库存场景,用‘商品ID+订单ID’作为唯一键
- 基于状态机去重,适合有严格状态流转的业务。比如订单状态只能从‘待支付’到‘已支付’再到‘已发货’,不能反向。
如何解决消息丢失问题
- 消息生产阶段:保障生产者到MQ不丢消息,一是开启生产者确认机制,MQ 收到消息后会给生产者返回确认,没收到确认就重试;二是关键消息落库,生产者发送前先把消息存到本地数据库,等收到 MQ 确认后再标记为 “已发送”,若重试失败,后续通过定时任务重新发送,彻底避免 “发了没收到” 的问题。
- 消息存储阶段:一是开启消息持久化,不管是RabbitMQ还是Kafka,都要配置持久化参数,避免内存中的消息因宕机丢失;二是MQ集群部署,用主从架构或分布式集群,主节点故障时,从节点能切换成新主,且从节点已同步了消息,不会导致数据丢失。
- 消息消费阶段:关闭消费者自动确认,改用手动确认。消费者拿到消息后,先执行业务逻辑,只有确认业务处理成功,再手动给 MQ 发送 ACK;如果处理失败,不发送 ACK,MQ 会认为消息没处理,等消费者恢复后重新推送。
如何处理消息队列的消息积压问题
消息积压是因为生产者的速度大于消费者。
,核心思路是 “先止损(快速消费掉积压消息),再根治(找到积压根源并优化)”,需分 “紧急处理” 和 “长期优化” 两步走,同时避免处理过程中引发新问题(如下游服务被压垮)。
- 紧急处理:快速消化已积压的消息
- 临时扩容消费者:快速扩容消费者实例,提高并发处理能力
- 优化消费逻辑:减少单条消息处理耗时,同步改异步,批量处理
- 临时分流:避免新消息加剧积压。若上游生产者仍在持续发消息,可临时分流部分消息到 “备用队列”,优先处理主队列积压,待主队列清完后再处理备用队列。
- 长期优化:找到积压根源,避免再次发生
- 消费端容错优化
- 下游服务优化
如何保证数据一致性,事务消息如何实现
- 生产者产生消息,发送一条半事务消息到mq
- mq收到消息,将消息持久化到存储系统,这条消息的状态是待发送
- mq返回ack给生产者
- 生产者执行本地事务
- 如果本地事务执行成功,则commit执行结果到mq,否则发送rollback
- 如果是正常的commit,mq修改消息状态为可发送,如果是rollback则删除消息
- 如果消息状态更新为可发送,mq会push消息给消费者,消费者消费完成返回ack
- 如果mq长时间没受到commit,会反查生产者,根据查询结果执行最终状态
消息队列是参考哪种设计模式
- 发布-订阅模式:这是消息队列的核心模式。生产者发送消息到队列,多个消费者同时接收消息(根据主题或队列分组)。
- 观察者模式:消息队列可视为 “被观察者”,消费者是 “观察者”。当队列中有新消息时,会通知订阅的消费者处理,本质是一种松耦合的通知机制
- 生产者-消费者模式:生产者生成消息并放入队列,消费者从队列中获取消息并处理,队列作为缓冲区隔离两者,避免直接交互,实现异步通信和削峰填谷。