消息队列MQ

本文介绍了MQ作为解耦利器,实现异步通信和削峰的效果。探讨了RabbitMQ的镜像集群与Kafka的高可用特性,以及如何在MQ中实现消息必达和幂等性,确保系统的稳定和数据一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解耦利器:MQ

A系统发送数据到BCD系统,明明需要数据的是BCD,更改代码却需要在A系统实现,架构中出现了反向依赖
在这里插入图片描述

使用MQ,A系统产生数据发送到MQ里,哪个系统需要数据则去MQ消费,如果不需要就取消订阅。A不需要考虑给谁发消息
在这里插入图片描述
通过MQ,A 系统就跟其它系统解耦了

异步通信

在这里插入图片描述
上游不关心下游执行结果,用户请求发送消息到MQ直接返回。
在这里插入图片描述

削峰

高峰期不论发送多少请求系统只处理MQ放行请求,减轻底层DB压力

MQ的高可用

RabbitMQ的镜像集群模式

元数据和队列(queue)都在多个实例上,每个RabbitMQ节点都有queue的完整镜像
在这里插入图片描述
优点:高可用,不怕宕机
缺点:性能开销大,非分布式,没有扩展性

Kafka的高可用

Kafka由多个节点(broker)组成,topic由partition组成,存在于不同节点上,topic分散在多个机器上,Kafka是一个天然的分布式消息队列

RabbitMQ一个queque都是放在一个节点里的,不是分布式
Kafka在0.8以前没有副本,一个broker宕机=所有partition消失

Kafka 0.8以后提供了高可用机制(High Availability),就是副本机制(replica),每个partition的数据都同步到其他机器上,形成多个副本,所有副本选举一个领袖(leader),消费与生产者只和leader副本交互,leader会把数据同步到其他副本上(保证了数据的一致性,系统简单高效)

如果一个broker宕机,副本就重新选举leader,保证高可用

写数据时,生产者只写入leader副本,其他副本自动从leader中拉取数据,一旦所有数据同步完成,就返回确认字符(ack)给leader,leader再返回成功消息给生产者

消费时,只从leader读取数据,但是只有所有副本同步成功,并且返回确认字符,消费者才能读取到

保证消息必达

在这里插入图片描述

  1. 发送方调用SendMsg接口,把消息发送给消息队列

  2. 消息队列让消息落地,写入数据库,落地=成功

  3. 消息队列调用SendCallback接口,把确认字符返回给发送方

  4. MQ调用RecvCallback接口,把消息发送给接收方

  5. 接收方调用SendAck,回复MQ

  6. MQ接收到确认字符ACK,将已经落地的消息删除

设置一个timer,当消息超时或者丢失时,timer会重发消息,直到收到消息落地的消息,如果重传N次还没收到,就返回发送失败

为了保证消息必达:

  1. 收到消息先落地
  2. 通过超时,重传,确认保证消息必达

对于RabbitMQ,生产者需要开启confirm模式,每次写消息生产者都会分配一个唯一id,发送到RabbitMQ中,RabbitMQ开启消息持久化,将消息持久化到磁盘中,消费者关闭自动ack机制,手动回传确认消息

MQ的幂等性

为了保证消息必达,可能导致接收方或发送方收到重复消息
所以必须保证消息总线的幂等性
在这里插入图片描述
如果消息队列返回确认字符时消息丢失,发送端会重发消息
为了避免数据重复落地,MQ需要生成内部消息ID

  1. 全局唯一
  2. MQ生成,业务无关
  3. MQ保证幂等

如果接收方返回确认字符时消息丢失,消息队列会重发消息
为了保证业务幂等性,业务消息中必须有业务ID

  1. 同一个业务,全局唯一
  2. 发送方生成,业务相关
  3. 消费方判重,保证幂等

生产者发送每条数据时先生成一个全局唯一的订单ID,到达消费者之前先去Redis中查一下之前是不是消费过,没消费就写入Redis,消费了就不处理了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值