首页 > 其他分享 >如何处理消息队列消费过程中的重复消息

如何处理消息队列消费过程中的重复消息

时间:2022-12-19 11:37:41浏览次数:32  
标签:请求 队列 重复 token 消息 数据 ID once


在 MQTT 协议中,给出了三种传递消息时能够提供的服务质量标准,这三种服务质量从低到高依次是:

  • ​At most once​​: 至多一次。消息在传递时,最多会被送达一次。换一个说法就是,没什么消息可靠性保证,允许丢消息。一般都是一些对消息可靠性要求不太高的监控场景使用,比如每分钟上报一次机房温度数据,可以接受数据少量丢失。
  • ​At least once​​: 至少一次。消息在传递时,至少会被送达一次。也就是说,不允许丢消息,但是允许有少量重复消息出现。
  • ​Exactly once​​:恰好一次。消息在传递时,只会被送达一次,不允许丢失也不允许重复,这个是最高的等级。

这个服务质量标准不仅适用于 MQTT,对所有的消息队列都是适用的。我们现在常用的绝大部分消息队列提供的服务质量都是 At least once,包括 RocketMQ、RabbitMQ 和 Kafka 都是这样。也就是说,消息队列很难保证消息不重复。

出现消息重复可以用幂等性解决,同样接口重复请求也可以用幂等解决

什么是幂等

幂等本来是数学上的概念,它的定义是这样的: 如果一个函数 f(x) 满足:f(f(x)) = f(x),则函数 f(x) 满足幂等性。比如,求绝对值的函数,abs(x) = abs(abs(x))。

在计算机领域用来描述一个操作、方法或者服务。一个幂等操作的特点是,其任意多次执行所产生的影响均与一次执行的影响相同。


场景

将林志玲账户的余额加 100 元

方法一:利用数据库的唯一约束实现幂等(利用数据库实现幂等性)

我们在数据库中建一张转账流水表,这个表有三个字段:转账单 ID、账户 ID 和变更金额,然后给转账单 ID 和账户 ID 这两个字段联合起来创建一个唯一约束,这样对于相同的转账单 ID 和账户 ID,表里至多只能存在一条记录。

方法二:为更新的数据设置前置条件(将方法实现幂等)

  1. 方法入参传入林志玲的账户余额,拿参数中的余额与数据库中的余额做比较如果相同则执行变更操作。
  2. 最简单的做法给数据增加一个版本号属性,每次更改数据前,比较当前数据的版本号是否和消息中的版本一致,如果不一致就拒绝更新数据,更新数据的同时将版本号 1。(和乐观锁原理一样)

方法三(建议使用此方法): 令牌机制(全局ID) (记录并检查操作)

在发送消息时,给每条消息指定一个全局唯一的ID,消费时,先根据这个ID检查这条消息是否有被消费过,如果没有消费过更新数据,然后将消费状态置为已消费。
方式一: 服务器端派发token并将token记录在缓存中, 客户端携带此token请求服务, 如果此token有效证明是有效请求,处理请求, 删除token。token无效忽略此请求。
方式二: 客户端请求携带一个唯一标识(流水),服务器判断此流水是否已经存在,如果已存在忽略此请求。


标签:请求,队列,重复,token,消息,数据,ID,once
From: https://blog.51cto.com/u_10176086/5951811

相关文章

  • 基于消息队列实现分布式事务
    注意:本文把消息队列与购物车系统看作同一个事务目标:掌握消息队列的事务场景:订单系统产生订单,购物车系统减购物车中的商品。实现思路:订单系统在消息队列上开启一个事务......
  • 队列总结_legend
    队列总结:Queue (1)队列的基本知识:        (1.1)特点:尾进头出,先进先出。(rearinfrontout)         (1.2)与线性表比较:        队列......
  • 架构设计(六):引入消息队列
    架构设计(六):引入消息队列作者:Grey原文地址:博客园:架构设计(六):引入消息队列CSDN:架构设计(六):引入消息队列消息队列是一个支持持久化的组件,数据存储在内存中,支持异步通信。它......
  • cpp优先队列(priority_queue)
    优先队列的概念在优先队列中,队列中的每个元素都与某个优先级相关联,但是优先级在队列数据结构中不存在。优先队列中具有最高优先级的元素将被首先删除,而队列遵循FIFO(......
  • 最长连续不重复子序列
    题目:给定一个长度为 n 的整数序列,请找出最长的不包含重复的数的连续区间,输出它的长度。输入:第一行包整数n,第二行包含n个整数(均在0∼100000范围内),表示整数序列。输......
  • 链表--删除无序链表中重复的节点
    题目:给定一个无顺序单链表的头节点head,删除其中值重复的元素思路:利用哈希表。生成一个哈希表,因为头节点是没有必要去删除的节点,所以首先将头节点放入哈希表;从头......
  • 详解逻辑回归与评分卡-用逻辑回归制作评分卡-重复值和缺失值处理【菜菜的sklearn课堂
    视频作者:菜菜TsaiTsai链接:【技术干货】菜菜的机器学习sklearn【全85集】Python进阶_哔哩哔哩_bilibili在银行借贷场景中,评分卡是一种以分数形式来衡量一个客户的信用风......
  • springboot + rabbitmq发送邮件(保证消息100%投递成功并被消费)
    一、先扔一张图image.png说明:本文涵盖了关于RabbitMQ很多方面的知识点,如:消息发送确认机制消费确认机制消息的重新投递消费幂等性,等等这些都是围绕上面那张整体流程图......
  • 【SpringBoot】使用WebSocket做消息对话
    Http协议只能客户端发送---服务器回复,无法做到服务器主动向客户端发送消息,所以可以使用websocket来进行双向通道发消息 研究了一下抖音斗鱼的弹幕也是用的websocket,......
  • 精华推荐 | 【深入浅出RocketMQ原理及实战】「性能原理挖掘系列」透彻剖析贯穿RocketM
    什么是事务消息事务消息(TransactionalMessage)是指应用本地事务和发送消息操作可以被定义到全局事务中,要么同时成功,要么同时失败。RocketMQ的事务消息提供类似X/OpenXA......