关于MQ的几件小事(三)如何保证消息不重复消费
1.幂等性
幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。
在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,“setTrue()”函数就是一个幂等函数,无论多次执行,其结果都是一样的.更复杂的操作幂等保证是利用唯一交易号(流水号)实现.
简单来说,幂等性就是一个数据或者一个请求,给你重复来了多次,你得确保对应的数据是不会改变的,不能出错。
2.出现重复消费场景
(1)首先,比如rabbitmq、rocketmq、kafka,都有可能会出现消息重复消费的问题。因为这个问题通常不是由mq来保证的,而是消费方自己来保证的。
(2)举例kafka来说明重复消费问题
kafka有一个叫做offset的概念,就是每个消息写进去,都有一个offset代表他的序号,然后consumer消费了数据之后,每隔一段时间,会把自己消费过的消息的offset提交一下,代表我已经消费过了,下次就算重启,kafka就会让消费者从上次消费到的offset来继续消费。
但是万事总有例外,如果consumer消费了数据,还没来得及发送自己已经消费的消息的offset就挂了,那么重启之后就会收到重复的数据。

3.保证幂等性(重复消费)
要保证消息的幂等性,这个要结合业务的类型来进行处理。下面提供几个思路供参考:
(1)、可在内存中维护一个set,只要从消息队列里面获取到一个消息,先查询这个消息在不在set里面,如果在表示已消费过,直接丢弃;如果不在,则在消费后将其加入set当中。
(2)、如何要写数据库,可以拿唯一键先去数据库查询一下,如果不存在在写,如果存在直接更新或者丢弃消息。
(3)、如果是写redis那没有问题,每次都是set,天然的幂等性。
(4)、让生产者发送消息时,每条消息加一个全局的唯一id,然后消费时,将该id保存到redis里面。消费时先去redis里面查一下有么有,没有再消费。
(5)、数据库操作可以设置唯一键,防止重复数据的插入,这样插入只会报错而不会插入重复数据。
上一篇《如何保证消息队列的高可用》
下一篇《如何防止数据队列数据丢失》
关于MQ的几件小事(三)如何保证消息不重复消费的更多相关文章
- 关于MQ的几件小事:如何保证消息队列的高可用
原文:https://www.cnblogs.com/jack1995/p/10908797.html 1.RabbitMQ的高可用 RabbitMQ基于主从模式实现高可用.RabbitMQ有三种模式 ...
- 关于MQ的几件小事(一)消息队列的用途、优缺点、技术选型
1.为什么使用消息队列? (1)解耦:可以在多个系统之间进行解耦,将原本通过网络之间的调用的方式改为使用MQ进行消息的异步通讯,只要该操作不是需要同步的,就可以改为使用MQ进行不同系统之间的联系,这样 ...
- 关于MQ的几件小事(六)消息积压在消息队列里怎么办
1.大量消息在mq里积压了几个小时了还没解决 场景:几千万条数据在MQ里积压了七八个小时,从下午4点多,积压到了晚上很晚,10点多,11点多.线上故障了,这个时候要不然就是修复consumer的问题, ...
- 关于MQ的几件小事(四)如何保证消息不丢失
1.mq原则 数据不能多,也不能少,不能多是说消息不能重复消费,这个我们上一节已解决:不能少,就是说不能丢失数据.如果mq传递的是非常核心的消息,支撑核心的业务,那么这种场景是一定不能丢失数据的. 2 ...
- 关于MQ的几件小事(七)如果让你设计一个MQ,你怎么设计
其实回答这类问题,说白了,起码不求你看过那技术的源码,起码你大概知道那个技术的基本原理,核心组成部分,基本架构构成,然后参照一些开源的技术把一个系统设计出来的思路说一下就好 比如说这个消息队列系统,我 ...
- 关于MQ的几件小事:消息队列的用途、优缺点、技术选型
原文:https://www.cnblogs.com/jack1995/p/10908789.html 1.为什么使用消息队列? (1)解耦:可以在多个系统之间进行解耦,将原本通过网络之间的调用的方式 ...
- 关于MQ的几件小事(五)如何保证消息按顺序执行
1.为什么要保证顺序 消息队列中的若干消息如果是对同一个数据进行操作,这些操作具有前后的关系,必须要按前后的顺序执行,否则就会造成数据异常.举例: 比如通过mysql binlog进行两个数据库的数据 ...
- 关于MQ的几件小事(二)如何保证消息队列的高可用
1.RabbitMQ的高可用 RabbitMQ基于主从模式实现高可用.RabbitMQ有三种模式:单机模式,普通集群模式,镜像集群模式. (1)单机模式: 单机模式就是demo级别的,生产中不会有人使 ...
- 关于redis的几件小事(三)redis的数据类型与使用场景
1.string 这是最基本的类型了,就是普通的set和get,做简单的kv缓存. 2.hash 这个是类似map的一种结构,这个一般就是可以将结构化的数据,比如一个对象(前提是这个对象没嵌套其他的对 ...
随机推荐
- #软件更新#Visual Studio更新到16.3.8
#软件更新#Visual Studio更新到16.3.8 此次更新包括以下内容:(1)支持Xcode 11.2.(2)修复无法从System.String类型转化的bug.(3)修复UWP开发中,加载 ...
- PHP 自动加载类
类的自动加载 (Autoloading Classes) 在编写面向对象(OOP) 程序时,很多开发者为每个类新建一个 PHP 文件. 这会带来一个烦恼:每个脚本的开头,都需要包含(include)一 ...
- 查询数据,从链接地址中爬取文章内容jsoup
查询数据,从链接地址中爬取文章内容 protected void doGet(HttpServletRequest request, HttpServletResponse response) thr ...
- Spring cloud微服务安全实战-5-11实现基于token的SSO(1)
基于服务器session的SSO的方案,用户的登陆状态都是存在服务器端的 基于浏览器cookie的token实现一个sso,在原来的基础上做进一步的改造.让他不依赖session.而是完全由cooki ...
- Qt编写气体安全管理系统18-数据库设置
一.前言 作为一个管理系统,数据库肯定是不可或缺的,Qt内置的sqlite数据库已经是够用的,而且本人亲测数据量能支持亿级别,而不是像网上很多人说的千万级别,我模拟过一亿多条数据,依然能够很好的查询, ...
- 转 mysql 存储过程初探
https://www.cnblogs.com/qmfsun/p/4838032.htmlMySQL命令执行sql文件的两种方法 https://www.cnblogs.com/mark-chan/p ...
- visual studio 2017搭建linux c++开发环境
https://blog.csdn.net/cekonghyj/article/details/77917433 https://blog.csdn.net/norsd/article/details ...
- 配置jdbc问题 mysql与IDEA
1.新建lib文件夹,将jar文件导入 2在structure中添加jar文件 3设置url时需要设置时区: import java.sql.Connection;import java.sql.Dr ...
- Ubuntu bashrc profile environment 区别
在 Ubuntu 中有如下几个文件可以设置环境变量: /etc/profile:在登录时,操作系统定制用户环境时使用的第一个文件,此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. ...
- 1144: 零起点学算法51——数组中删数(C语言)
题目: 题目来源WUSTOJ 源代码: #include<stdio.h> int main() { int n, m, i, a[20]; while (scanf("%d&q ...