怎样保证消息队列的消息只能被消费一次

打印 上一主题 下一主题

主题 1943|帖子 1943|积分 5829

怎样保证消息队列的消息只能被消费一次,首先先保证消息不会丢失
首先先生产者到消费者到消费者有哪些场景会消息丢失

一、问题场景
场景一、生产者发送到消息队列失败
场景二、消息队列接受到消息磁盘化失败
场景三、消费者接受到消息消费失败
二、场景原因,怎样解决
1、场景一失败的原因:大概出现在生产者发送给消息队列消息时大概会出现网络抖动,导致发送失败。也有大概消息队列服务挂掉导致发送失败。
解决方法:可以接纳消息重传的方式,先可以接纳在内存中重试几次,如果重试次数达到最大重试次数,将该消息放到一张记载表中,延时重发即可。当然这种做法大概会有重复消息,
这里只需要确保消息发送到消息队列即可,怎样保证消息发送到消息队列,以rocketMQ为例,确保rocketMQ开启ack确认机制,当rocketMQ接受到消息会返回给生产者一条
ack,当生产者收到了ack才阐明此条消息到达了rocketMQ,若没有收到一律按照重传处理
2、场景二失败的原因:会出现这种原因是因为消息队列将消息持久化机制有关。持久化机制有两种,一种是异步刷盘,一种是同步刷盘。
异步刷盘是生产者将消息发送给消息队列,消息队列并不是将消息立即将消息存到磁盘,而是将消息消息存到内存或者操纵系统的缓存里,消息累计到肯定的数目才会将消息持久化到磁盘上,这时消息在内存到中消息队列就会发送给生产者一条消息确认消息,在单机的状态下,如果消息没有消费消息队列重启或者挂掉会导致消息丢失。在集群的环境下也有大概会出现消息丢失,当主节点收到生产者的消息,在主节点和从节点消息同步时,主节点还没有消息持久化,没有同步给从节点,这个时候主节点挂点,从节点晋升为主节点,这个时候会出现消息丢失
同步刷盘是将消息持久化到磁盘中才会返回给生产者ack。

解决方法:将消息队列消息持久化设置成同步刷盘就可以解决这个问题
3、场景三失败原因:以上两点只需要保证消息不丢失即可。那为什么消费者也会出现消息的丢失呢?有几个原因,第一个原因当消费者还有没有消费完消费者出现了宕机或者异常,提前将进度更新到消息队列中,消息队列就不会重复的消费了。第二个原因生产者生产重复消息到了消费者,消费者无法重复消费消息。
解决方法:

首先消费者先插入一个消费记载表,插入成功就实行业务代码,业务代码步伐成功就更新记载表状态,业务代码未实行成功,删除记载表中的数据重新实行,如果是bug可以人工干预一下。如果插入记载表失败,检查记载表的状态。如果说已经完成,直接返回消费成功,如果是未完成,耽误消费即可。
这个时候会有一个问题,如果在实行业务代码时出现了宕机等状况,没有来得及删除删除记载表数据,会出现消息开始 -> 插入状态 ->耽误消费的死循环,这个时候就需要人工干预,或者记载消息消费的消费次数时候还是不是需要再消费

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

知者何南

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表