RabbitMQ消息不丢失补偿方案

「扫码关注我,面试、各种技术(mysql、zookeeper、微服务、redis、jvm)持续更新中~」
在这里插入图片描述

RabbitMQ特性

  • 异步
  • 解耦
  • 削峰填谷

正是由于其存在以上特性,所以被广泛应用于实际开发中,但是线上环境却存在消息丢失的场景,需要我们通过一些技术手段来保证最终数据的一致性(即MQ消息不丢失),首先我们先需要了解下RabbitMQ整体的架构图如下:

RabbitMQ架构图

RabbitMQ组成

通过上面架构图我们可以看到RabbitMQ大致分为3部分,

  1. 客户端(生产者)
  2. RabbitMQ消息中间件
  3. 服务端(消费者)

RabbitMQ消息丢失原因

那么究竟哪些环节会导致消息丢失呢?

  • 生产者发送消息到RabbitMQ服务器后,RabbitMQ服务器出现宕机
  • RabbitMQ服务器出现类似脑裂问题后重启服务
  • 消费者接收到MQ消息后出现宕机或者业务处理异常

RabbitMQ消息丢失解决方案

那么根据以上可能存在的问题,我们需要通过一些手段来保证消息不丢失。

生产者confirm模式

​ 首先针对生产者发送消息到RabbitMQ服务器后,RabbitMQ服务器出现宕机的情况,生产者在发送消息给RabbitMQ服务器时,事务消息可以保证消息发送到RabbitMQ服务器,事务的实现主要是对信道(Channel)的设置,主要的方法有三个:

  • channel.txSelect()声明启动事务
  • channel.txComment()提交事务
  • channel.txRollback()回滚事务

但是以上事务会降低大约2~10倍的吞吐量,而且会使生产者和应用程序产生同步,而我们使用RabbitMQ通信的目的就是要避免同步。所以,RabbitMQ团队有更好的方案来保证消息投递:发送方确认模式。当然你需要告诉Rabbit将信道设置成confirm模式。Confirm的三种实现方式:

  • channel.waitForConfirms()普通发送方确认模式
  • channel.waitForConfirmsOrDie()批量确认模式
  • channel.addConfirmListener()异步监听发送方确认模式;

消息持久化

​ 接下来我们讨论如何解决RabbitMQ服务器出现类似脑裂问题后重启服务导致消息丢失的问题,如果RabbitMQ重启之后,那些队列和交换器就会都消失了(随同里面都消息)。原因是每个队列和交换器都durable默认为false,他决定了RabbitMQ重启或宕机后需要重新建立交换器和队列,那么当我们将durable属性设置为true后,交换器和队列是不会重建了,但是消息却还会消失,能从AMQP服务器崩溃中恢复的消息,我们称之为消息的的持久化。在发布消息前,通过把他的投递模式选项设置为2来把消息标记为持久化。Java中设置方式为channel.basicPublish("", QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes()); 但是消息持久化会带来性能问题,影响RabbitMQ的吞吐量,所以要适当取舍。但是这里要注意一点,RabbitMQ的消息持久化,是不承诺100%的消息不丢失的。

消费者补偿消息

​ 最后我们讨论消费者接收到MQ消息后出现宕机或者业务处理异常的情景应该如何处理,消费者消息丢失的主要原因是由于当消费者接收到RabbitMQ的消息后,是手动ack还是自动ack,如果业务量不大话可以使用手动ack的方式,这样的话RabbitMQ就不会盲目的投递消息到消费者后,立马就删除消息了,说白了就是不会自作主张的认为消息处理成功了,但是手动ack在业务量较大的情况下会影响系统的吞吐量,如果消费出现异常还有可能会导致消息积压,因此我们采取的是自动ack的方式,那么这样的话又如何保证消息不丢失呢?

​ 我们消息补偿的架构图如下:

image.png

生产者发送消息

1.1 生产者发送消息到RabbitMQ服务器

1.2 RabbitMQ通过异步confirm方式通知生产者消息接收完成

1.3 生产者可以异步将消息存入ES(备份消息),防止MQ服务器重启导致消息丢失,当然交换机、队列和消息现在是持久化状态

消费者消费消息

2.1 消费者接收数据

2.2 接收到消息首先写入ES

2.3 业务处理完成后删除ES中到消息

补发定时任务

3 定时任务补发消费失败消息并更新补发次数

报警定时任务

4 定时任务抓去补发超过3次消息钉钉报警人工干预

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值