原文作者:weixin_49367803

原文地址:https://blog.csdn.net/weixin_49367803/article/details/108480256

一、如何保证消息不被重复消费?

1、保证消息不被重复消费的关键是保证消息队列的幂等性,这个问题针对业务场景来答分以下几点:

  • 比如,你拿到这个消息做数据库的insert操作。那就容易了,给这个消息做一个唯一主键,那么就算出现重复消费的情况,就会导致主键冲突,避免数据库出现脏数据。
  • 再比如,你拿到这个消息做redis的set的操作,那就容易了,不用解决,因为你无论set几次结果都是一样的,set操作本来就算幂等操作。
  • 如果上面两种情况还不行,上大招。准备一个第三方介质,来做消费记录。以redis为例,给消息分配一个全局id,只要消费过该消息,将<id,message>以K-V形式写入redis。那消费者开始消费前,先去redis中查询有没消费记录即可。

二、如何解决丢数据的问题?

1、生产者丢数据

生产者的消息没有投递到MQ中怎么办?从生产者弄丢数据这个角度来看,RabbitMQ提供transaction和confirm模式来确保生产者不丢消息。

transaction机制就是说,发送消息前,开启事物(channel.txSelect()),然后发送消息,如果发送过程中出现什么异常,事务就会回滚(channel.txRollback()),如果发送成功则提交事物(channel.txCommit())。然而缺点就是吞吐量下降了。

因此,按照博主的经验,生产上用confirm模式的居多。一旦channel进入confirm模式,所有在该信道上面发布的消息都将会被指派一个唯一的ID(从1开始),一旦消息被投递到所有匹配的队列之后,rabbitMQ就会发送一个Ack给生产者(包含消息的唯一ID),这就使得生产者知道消息已经正确到达目的队列了。如果rabiitMQ没能处理该消息,则会发送一个Nack消息给你,你可以进行重试操作。

2.消息队列丢数据

处理消息队列丢数据的情况一般是开启持久化磁盘的配置。这个持久化配置可以和confirm机制配合使用,你可以在消息持久化磁盘后,再给生产者发送一个Ack信号。这样,如果消息持久化磁盘之前,rabbitMQ阵亡了,那么生产者收不到Ack信号,生产者会自动重发。那么如何持久化呢,这里顺便说一下吧,其实也很容易,就下面两步:

①将queue的持久化标识durable设置为true,则代表是一个持久的队列

②发送消息的时候将deliveryMode=2这样设置以后,rabbitMQ就算挂了,重启后也能恢复数据。在消息还没有持久化到硬盘时,可能服务已经死掉,这种情况可以通过引入mirrored-queue即镜像队列,但也不能保证消息百分百不丢失(整个集群都挂掉)

3.消费者丢数据

启用手动确认模式可以解决这个问题

①自动确认模式,消费者挂掉,待ack的消息回归到队列中。消费者抛出异常,消息会不断的被重发,直到处理成功。不会丢失消息,即便服务挂掉,没有处理完成的消息会重回队列,但是异常会让消息不断重试。

②手动确认模式,如果消费者来不及处理就死掉时,没有响应ack时会重复发送一条信息给其他消费者;如果监听程序处理异常了,且未对异常进行捕获,会一直重复接收消息,然后一直抛异常;如果对异常进行了捕获,但是没有在finally里ack,也会一直重复发送消息(重试机制)。

③不确认模式,acknowledge=“none” 不使用确认机制,只要消息发送完成会立即在队列移除,无论客户端异常还是断开,只要发送完就移除,不会重发。

三、如何保证消息的顺序性?

针对这个问题,通过某种算法,将需要保持先后顺序的消息放到同一个消息队列中。然后只用一个消费者去消费该队列。同一个queue里的消息一定是顺序消息的。我的观点是保证入队有序就行,出队以后的顺序交给消费者自己去保证,没有固定套路。例如B消息的业务应该保证在A消息后业务后执行,那么我们保证A消息先进queueA,B消息后进queueB就可以了。

RabbitMQ—重复消费、数据丢失和消息顺序性相关推荐

  1. 消息队列、RabbitMQ原理、消息队列保证幂等性,消息丢失,消息顺序性,以及处理消息队列消息积压问题

    消息队列 消息队列(Message Queue,简称MQ),从字面意思上看,本质是个队列,FIFO先入先出,只不过队列中存放的内容是message而已 常见的消息队列 RabbitMq ActiveM ...

  2. RabbitMQ常见幂等性、可靠性、顺序性问题及解决方案

    目录 如何保证幂等性 什么是幂等性 重复消费产生的场景 解决方案 如何保证可靠性 产生原因 解决方案 如何保证顺序性 产生原因 解决方案 参考 如何保证幂等性 如果消息的重复消费对业务有影响,那么就需 ...

  3. Kafka中是怎么体现消息顺序性的?

    Kafka只能保证分区内消息顺序有序,无法保证全局有序 生产者:通过分区的leader副本负责数据顺序写入,来保证消息顺序性 消费者:同一个分区内的消息只能被一个group里的一个消费者消费,保证分区 ...

  4. 详解,最新整理,RabbitMQ,RocketMQ,Kafka 事务性,消息丢失,消息顺序性和消息重复发送的处理策略

    消息队列常见问题处理 分布式事务 什么是分布式事务 我们的服务器从单机发展到拥有多台机器的分布式系统,各个系统之前需要借助于网络进行通信,原有单机中相对可靠的方法调用以及进程间通信方式已经没有办法使用 ...

  5. RabbitMQ,RocketMQ,Kafka 事务性,消息丢失,消息顺序性和消息重复发送的处理策略

    消息队列常见问题处理 分布式事务 什么是分布式事务 我们的服务器从单机发展到拥有多台机器的分布式系统,各个系统之前需要借助于网络进行通信,原有单机中相对可靠的方法调用以及进程间通信方式已经没有办法使用 ...

  6. #rabbitMQ #重复消费 #可靠投递 #延时投递 #rabbitMQ交换机类型#重复消费#消息积压#消息丢失

    exchange类型: 1, direct 指定direct后, 消息会根据你设置的routeing key(路由键), 发送到对应的队列中 1,新建direct交换机 2,添加队列, 并且绑定路由键 ...

  7. rabbitmq如何保证消息不被重复消费_RabbitMQ保证消息可靠投递与消费的正确使用姿势...

    前言 MQ 是什么?MQ 我们可以理解为消息队列. 队列是什么?队列我们可以理解为管道. 即以管道的方式做消息传递. 场景展示: 1.我们在双11的凌晨大量秒杀和抢购商品,然后去结算的时候,发现界面会 ...

  8. 如何保证消息不被重复消费~~~~~(如何保证消息队列的幂等性)

    分析:这个问题其实换一种问法就是,如何保证消息队列的幂等性?这个问题可以认为是消息队列领域的基本问题.换句话来说,是在考察你的设计能力,这个问题的回答可以根据具体的业务场景来答,没有固定的答案. 回答 ...

  9. RabbitMQ 可靠性、重复消费、顺序性、消息积压解决方案

    前言 为什么引入消息队列?引入 MQ 给我们解决了一些问题,但同时又引入了一些复杂的问题,这些问题是大型项目中必须解决的重点,更重要的是,面试也经常问.实际上消息队列可以说是没法百分之百保证可靠性的! ...

最新文章

  1. CPU消耗,跟踪定位理论与实践
  2. 用Response.Write和Page.RegisterStartupScript显示的提示框有什么区别
  3. 嵌入式linux支持python,【python】嵌入式设备上python的使用
  4. 介绍几种SSIS部署方式
  5. smartform 打印预览时转PDF查看
  6. Java基础 集合(Collection)结构详解 Collection和Collections的区别
  7. iOS的runtime运行时机制
  8. 命令行下的mysql的基本操作
  9. .NET下使用socket.io随笔记录
  10. Visual C++编程中的文件操作
  11. oracle 批量杀死 死锁进程
  12. 手把手带你阅读Mybatis源码(一)构造篇
  13. 【渝粤教育】电大中专建筑力学 (2)作业 题库
  14. 序列化Image到byte[]
  15. 计算机主机电源功率查,电脑电源功率怎么测试?查看电脑功耗的操作方法
  16. 操作WORD文件:使用MSWORD.OLB组件将RichTextBox中的文本保存为WORD格式文件。
  17. 如何延缓衰老?十大抗衰小妙招!
  18. [转载]Ext.form.BasicForm getValues()和getFie_-Chaz-_新浪博客
  19. 如何将硬盘数据迁移包括系统一起迁移到另一个硬盘?
  20. Java 设计模式最佳实践:四、结构模式

热门文章

  1. Lucene 基础理论
  2. ObjectArx开发对txt文本文件的操作一例
  3. Node.Js同步mongdb数据
  4. 前后端分离之JWT用户认证
  5. Api文档生成工具与Api文档的传播(pdf)
  6. spring框架学习笔记2:配置详解
  7. Eclipse中看java源代码
  8. input和img图片水平对齐
  9. 你若安好,便是晴天。
  10. Confluence 6 使用 Apache 和 mod_proxy 添加 SSL和其他