消息队列MQ

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 之后,就会返回写成功的消息给生产者(也有其他模式)

RabbitMQKafka
每个实例有完整queue镜像每个机器只放部分数据,并用集群同步

4.重复消费问题

参考:
如何保证消息不被重复消费?(如何保证消息消费的幂等性)

幂等问题

原因:
网络延时

RabbitMQKafka
模式点对点/订阅者(消费完把消息删除)订阅者
生产者重复发送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.消息丢失

参考:
如何保证消息的可靠性传输?(如何处理消息丢失的问题)

RabbitMQKafka
生产者发送消息过程中丢失1.事务机制(同步,吞吐量低,影响性能)2.confirm机制(异步)在 producer 端设置 acks=all :要求每条数据,必须写入所有 replica 之后,才能认为成功。
MQ暂存内存中挂持久化:创建queue时持久化+发消息时持久化配置参数,保证有一个follower与leader同步
消费者没处理完就挂关闭自动ack,等处理完手动ack关闭自动提交offset,处理完手动提交offset

事务 vs confirm
事务:同步,阻塞
confirm:异步。MQ成功接收消息则ack,未能处理则nack,会返回给生产者,生产者不必等待处理结果,一段时间后没有收到结果可重发,MQ使用异步回调方式返回结果。

6.消息顺序性

参考:
如何保证消息的顺序性?

RabbitMQKafka
场景一个queue多个消费者消费,消息在queue中有序但消费时就乱序了同个partition但消费由于多线程无法保证顺序
解决方案拆分queue,每个queue对应一个消费者,消息投递到同个queue中由同个consumer消费写N个内存queue,每个线程消费同个queue

思路:让queue对应一个消费者一个线程,顺序消息到一个queue中

思考:RabbitMQ中消息在到达queue之前就乱序了呢?还是无法保证顺序。。。
Kafka因为sequence是顺序递增的一定能保证顺序

7.消息积压怎么解决?

参考:
积压问题

  1. 临时扩容,扩大queue和consumer加快消费速度
  2. 设置过期时间,数据会搞丢,事后要手动补数据
  3. 方案1和2结合,先快速消费,消费一个丢弃一个,之后再补数据

RocketMQ解决方案:

  1. 提高消费并行度
  2. 批量消费
  3. 丢弃不重要消息
  4. 优化消费过程

8.数据一致性

参考:
MQ消息最终一致性解决方案

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值