1.为什么使用消息队列
解耦:IM会话状态信息/班表消息(具体场景说明),有许多应用需要这个状态消息,上游应用不应该维护需要给哪些应用发送这些信息,采用发送消息的方式进行解耦。
异步:短信、邮件通知等场景(非必须),A需要调用BCD三个接口写库,使用消息就不必等3个接口都写完(耗时从A+B+C+D减少为A+消息发送延时)
削峰:高峰期系统拉取请求不会因为请求量高而挂掉(积压消息处理)
2.消息队列缺点
1.MQ挂了怎么办?消息高可用?
2.重复消费?消息丢失?消息顺序性?
3.数据一致性
3.高可用
典型的两种实现高可用方式:
基于主从(非分布式,RabbitMQ)
分布式(Kafka)
参考:
如何保证消息队列的高可用?
RabbitMQ
1.单机模式
2.普通集群(无高可用性)
queue只放在一台机器上,其他机器实例会同步queue的元数据,消费时拉取queue所在实例的数据。
主要提高吞吐量
3.镜像集群模式(高可用)
每个实例都有queue的完整镜像,生产消息时会同步到每个(或部分)实例上。(网络开销大,无法线性扩展!)
Kafka
天然的分布式消息队列,一个topic数据分成多个partition分散在多个机器上,每台机器就放一部分数据。
HA机制:Kafka 会均匀地将一个
partition 的所有 replica 分布在不同的机器上,只读写leader,写时同步follower,leader 收到所有 follower 的 ack 之后,就会返回写成功的消息给生产者(也有其他模式)
RabbitMQ | Kafka |
---|---|
每个实例有完整queue镜像 | 每个机器只放部分数据,并用集群同步 |
4.重复消费问题
参考:
如何保证消息不被重复消费?(如何保证消息消费的幂等性)
原因:
网络延时
RabbitMQ | Kafka | |
---|---|---|
模式 | 点对点/订阅者(消费完把消息删除) | 订阅者 |
生产者重复发送 | MQ-client生成inner-msg-id,全局唯一,业务无关,由MQ保证。 | producerId + sequence 1.sequence<=broker sequence丢弃消息 2. sequence==broker sequence+1,接收消息 3.sequence>broker sequence+1,丢失数据抛异常 |
消费重复 | 业务发送方带入biz-id,业务接收方去重保证幂等。业务唯一,业务相关,对MQ透明。 | 1.取消自动提交offset(没法保证不重复)2.下游做幂等 |
消费端幂等解决思路:
1.唯一键
2.Redis的set天然幂等
3.全局唯一id保存到Redis里
5.消息丢失
参考:
如何保证消息的可靠性传输?(如何处理消息丢失的问题)
RabbitMQ | Kafka | |
---|---|---|
生产者发送消息过程中丢失 | 1.事务机制(同步,吞吐量低,影响性能)2.confirm机制(异步) | 在 producer 端设置 acks=all :要求每条数据,必须写入所有 replica 之后,才能认为成功。 |
MQ暂存内存中挂 | 持久化:创建queue时持久化+发消息时持久化 | 配置参数,保证有一个follower与leader同步 |
消费者没处理完就挂 | 关闭自动ack,等处理完手动ack | 关闭自动提交offset,处理完手动提交offset |
事务 vs confirm
事务:同步,阻塞
confirm:异步。MQ成功接收消息则ack,未能处理则nack,会返回给生产者,生产者不必等待处理结果,一段时间后没有收到结果可重发,MQ使用异步回调方式返回结果。
6.消息顺序性
参考:
如何保证消息的顺序性?
RabbitMQ | Kafka | |
---|---|---|
场景 | 一个queue多个消费者消费,消息在queue中有序但消费时就乱序了 | 同个partition但消费由于多线程无法保证顺序 |
解决方案 | 拆分queue,每个queue对应一个消费者,消息投递到同个queue中由同个consumer消费 | 写N个内存queue,每个线程消费同个queue |
思路:让queue对应一个消费者一个线程,顺序消息到一个queue中
思考:RabbitMQ中消息在到达queue之前就乱序了呢?还是无法保证顺序。。。
Kafka因为sequence是顺序递增的一定能保证顺序
7.消息积压怎么解决?
参考:
积压问题
- 临时扩容,扩大queue和consumer加快消费速度
- 设置过期时间,数据会搞丢,事后要手动补数据
- 方案1和2结合,先快速消费,消费一个丢弃一个,之后再补数据
RocketMQ解决方案:
- 提高消费并行度
- 批量消费
- 丢弃不重要消息
- 优化消费过程
8.数据一致性
参考:
MQ消息最终一致性解决方案