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的几件小事(三)如何保证消息不重复消费的更多相关文章

  1. 关于MQ的几件小事:如何保证消息队列的高可用

    原文:https://www.cnblogs.com/jack1995/p/10908797.html 1.RabbitMQ的高可用 RabbitMQ基于主从模式实现高可用.RabbitMQ有三种模式 ...

  2. 关于MQ的几件小事(一)消息队列的用途、优缺点、技术选型

    1.为什么使用消息队列? (1)解耦:可以在多个系统之间进行解耦,将原本通过网络之间的调用的方式改为使用MQ进行消息的异步通讯,只要该操作不是需要同步的,就可以改为使用MQ进行不同系统之间的联系,这样 ...

  3. 关于MQ的几件小事(六)消息积压在消息队列里怎么办

    1.大量消息在mq里积压了几个小时了还没解决 场景:几千万条数据在MQ里积压了七八个小时,从下午4点多,积压到了晚上很晚,10点多,11点多.线上故障了,这个时候要不然就是修复consumer的问题, ...

  4. 关于MQ的几件小事(四)如何保证消息不丢失

    1.mq原则 数据不能多,也不能少,不能多是说消息不能重复消费,这个我们上一节已解决:不能少,就是说不能丢失数据.如果mq传递的是非常核心的消息,支撑核心的业务,那么这种场景是一定不能丢失数据的. 2 ...

  5. 关于MQ的几件小事(七)如果让你设计一个MQ,你怎么设计

    其实回答这类问题,说白了,起码不求你看过那技术的源码,起码你大概知道那个技术的基本原理,核心组成部分,基本架构构成,然后参照一些开源的技术把一个系统设计出来的思路说一下就好 比如说这个消息队列系统,我 ...

  6. 关于MQ的几件小事:消息队列的用途、优缺点、技术选型

    原文:https://www.cnblogs.com/jack1995/p/10908789.html 1.为什么使用消息队列? (1)解耦:可以在多个系统之间进行解耦,将原本通过网络之间的调用的方式 ...

  7. 关于MQ的几件小事(五)如何保证消息按顺序执行

    1.为什么要保证顺序 消息队列中的若干消息如果是对同一个数据进行操作,这些操作具有前后的关系,必须要按前后的顺序执行,否则就会造成数据异常.举例: 比如通过mysql binlog进行两个数据库的数据 ...

  8. 关于MQ的几件小事(二)如何保证消息队列的高可用

    1.RabbitMQ的高可用 RabbitMQ基于主从模式实现高可用.RabbitMQ有三种模式:单机模式,普通集群模式,镜像集群模式. (1)单机模式: 单机模式就是demo级别的,生产中不会有人使 ...

  9. 关于redis的几件小事(三)redis的数据类型与使用场景

    1.string 这是最基本的类型了,就是普通的set和get,做简单的kv缓存. 2.hash 这个是类似map的一种结构,这个一般就是可以将结构化的数据,比如一个对象(前提是这个对象没嵌套其他的对 ...

随机推荐

  1. flutter Form表单

    import 'package:flutter/material.dart'; class FormDemo extends StatelessWidget { @override Widget bu ...

  2. 在excel图表上添加数据标签

    在excel图表上添加数据标签 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 https://zhidao.baidu.com/question/47838665 方法与步骤 在E ...

  3. C# 子线程与主线程通讯方法一

    最近在项目中要用到子线程运行结束向主线程通知的需求,利用线程上下文来实现线程之间的同步. 子线程结束后调用同步函数,向主线程发送时间字符串,改变主窗体的label标签 label标签改变事件触发处理函 ...

  4. 安装kubernet(k8s)

    简介: 需要学习的都明白,这里就不赘述了. 本文采用CentOS-7-x86_64-DVD-1810.iso 一:安装操作系统 本来是喜欢用fedora的,但是fedora貌似包维护的不好,就又开始用 ...

  5. 石子合并 区间DP模板题

    题目链接:https://vjudge.net/problem/51Nod-1021 题意 N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石 ...

  6. linux如何查看mysql是否启动

    linux下有很多服务,今天就写一下如何查看服务是否启动,以mysql为例子 使用命令 # service mysqld status 或者 # service mysql status 命令来查看m ...

  7. 07点睛Spring MVC4.1-ContentNegotiatingViewResolver

    转发地址:https://www.iteye.com/blog/wiselyman-2214965 7.1 ContentNegotiatingViewResolver ContentNegotiat ...

  8. 基于libuv的TCP设计(一)

    本人一直在寻找一个跨平台的网络库,boost与ACE比较庞大,不考虑.对比了libevent,libev,libuv后,最终选择了libuv.可libuv文档少,例子也简单,对于tcp只有个echo- ...

  9. 因修改/etc/sudoers权限导致sudo和su不能使用的解决方法(转)

    转自: 因修改/etc/sudoers权限导致sudo和su不能使用的解决方法   系统环境:ubuntu 12.04 状况: 因为修改了/etc/sudoers以及相关权限,导致sudo无法使用,恰 ...

  10. Spring @Transactional 事务机制

    几个概念要清楚:事务的传播机制,事务的边界 工作原理 运行配置@Transactional注解的测试类的时候,具体会发生如下步骤 1)事务开始时,通过AOP机制,生成一个代理connection对象, ...