点戳蓝字“架构之美”关注我们哦!

前言

今天我们聊一个话题,这个话题大家可能在面试过程中,或者是工作当中经常遇到 ?如何保证 Kafka 消息不重复消费?我们在做开发的时候为了程序的健壮性,在使用 Kafka 的时候一般都会设置重试的次数,但是因为网络的一些原因,设置了重试就有可能导致有些消息重复发送了(当然导致消息重复也有可能是其他原因),那么怎么解决消息重复这个问题呢?关于这个问题,我这儿提供了如下三种解决方案,供大家参考。

解决方案

方案一  /  保存并查询给每个消息都设置一个独一无二的 key,消费的时候把 key 记录下来,然后每次消费新的消息的时候都查询一下,看当前消息的这个 key 是否消费过,如果没有消费过才进行消费。(这种方式好想,但是其实实现起来一点也不简单)方案二 /  利用幂等幂等(Idempotence)在数学上是这样定义的,如果一个函数 f(x) 满足:f(f(x)) = f(x),则函数 f(x) 满足幂等性。这个概念被拓展到计算机领域,被用来描述一个操作、方法或者服务。一个幂等操作的特点是,其任意多次执行所产生的影响均与一次执行的影响相同。一个幂等的方法,使用同样的参数,对它进行多次调用和一次调用,对系统产生的影响是一样的。所以,对于幂等的方法,不用担心重复执行会对系统造成任何改变。我们举个例子?来说明一下。在不考虑并发的情况下,“将 X 老师的账户余额设置为 100 万元”,执行一次后对系统的影响是,X 老师的账户余额变成了 100 万元。只要提供的参数 100万元不变,那即使再执行多少次,X 老师的账户余额始终都是 100万元,不会变化,这个操作就是一个幂等的操作。再举一个例子?,“将 X 老师的余额加 100 万元”,这个操作它就不是幂等的,每执行一次,账户余额就会增加 100 万元,执行多次和执行一次对系统的影响(也就是账户的余额)是不一样的。所以,通过这两个例子,我们可以想到如果系统消费消息的业务逻辑具备幂等性,那就不用担心消息重复的问题了,因为同一条消息,消费一次和消费多次对系统的影响是完全一样的。也就可以认为,消费多次等于消费一次。那么,如何实现幂等操作呢?最好的方式就是,从业务逻辑设计上入手,将消费的业务逻辑设计成具备幂等性的操作。但是,不是所有的业务都能设计成天然幂等的,这里就需要一些方法和技巧来实现幂等。下面我们介绍一种常用的方法:利用数据库的唯一约束实现幂等。例如,我们刚刚提到的那个不具备幂等特性的转账的例子:将 X 老师的账户余额加 100 万元。在这个例子中,我们可以通过改造业务逻辑,让它具备幂等性。首先,我们可以限定,对于每个转账单每个账户只可以执行一次变更操作,在分布式系统中,这个限制实现的方法非常多,最简单的是我们在数据库中建一张转账流水表,这个表有三个字段:转账单 ID、账户 ID 和变更金额,然后给转账单 ID 和账户 ID 这两个字段联合起来创建一个唯一约束,这样对于相同的转账单 ID 和账户 ID,表里至多只能存在一条记录。这样,我们消费消息的逻辑可以变为:“在转账流水表中增加一条转账记录,然后再根据转账记录,异步操作更新用户余额即可。”在转账流水表增加一条转账记录这个操作中,由于我们在这个表中预先定义了“账户 ID 转账单 ID”的唯一约束,对于同一个转账单同一个账户只能插入一条记录,后续重复的插入操作都会失败,这样就实现了一个幂等的操作。方案三 /  设置前置条件

为更新的数据设置前置条件另外一种实现幂等的思路是,给数据变更设置一个前置条件,如果满足条件就更新数据,否则拒绝更新数据,在更新数据的时候,同时变更前置条件中需要判断的数据。

这样,重复执行这个操作时,由于第一次更新数据的时候已经变更了前置条件中需要判断的数据,不满足前置条件,则不会重复执行更新数据操作。

比如,刚刚我们说过,“将 X 老师的账户的余额增加 100 万元”这个操作并不满足幂等性,我们可以把这个操作加上一个前置条件,变为:“如果X老师的账户当前的余额为 500万元,将余额加 100万元”,这个操作就具备了幂等性。

对应到消息队列中的使用时,可以在发消息时在消息体中带上当前的余额,在消费的时候进行判断数据库中,当前余额是否与消息中的余额相等,只有相等才执行变更操作。

但是,如果我们要更新的数据不是数值,或者我们要做一个比较复杂的更新操作怎么办?用什么作为前置判断条件呢?更加通用的方法是,给你的数据增加一个版本号属性,每次更数据前,比较当前数据的版本号是否和消息中的版本号一致,如果不一致就拒绝更新数据,更新数据的同时将版本号 +1,一样可以实现幂等。

最后

今天给大家提供的消息重复的解决方案,也参考了《消息队列高手课》里的思路,大家如果有什么好的解决方案,欢迎讨论!!大家加油!!

·end·

奈学教育科技

技术人成长之路的指路人

点赞支持技术创业?

三张表有重复字段_什么?搞不定Kafka重复消费?相关推荐

  1. 什么?搞不定Kafka重复消费?

    来自:架构之美 前言 今天我们聊一个话题,这个话题大家可能在面试过程中,或者是工作当中经常遇到 ????如何保证 Kafka 消息不重复消费?我们在做开发的时候为了程序的健壮性,在使用 Kafka 的 ...

  2. bartender外部表不是预期格式_三张表轻松搞定项目计划

    俗话说凡事预则立,我们做项目更要如此,其实生活也雷同,比如说小到买个家电,从预算.到品牌选择或者商场选择.到安装使用等整个过程. 下图展示计划的主要思考点,仅供参考 项目主要包括需求沟通和方案预研.需 ...

  3. 多对多关系需要建立中间表_【数据库基础】为什么需要三张表之多对多表结构设计...

    了解完一对一和一对多表结构设计,接下来一起了解一下多对多的表结构设计. 同样,咱们先来想一般什么场景需要用到多对多.假如说咱们有一个叫订单和一个叫商品的这两张表,这两张表的关系,它其实就是一个多对多的 ...

  4. 商品表有哪些字段_面试中有哪些经典的数据库问题?

    一.为什么用自增列作为主键 1.如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择主键作为聚集索引.如果没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主 ...

  5. 阿里规定超过三张表禁止JOIN,为啥呢?

    作者 | e71hao 来源 | http://blog.itpub.net/30393770/viewspace-2650450/ 一. 问题提出 <阿里巴巴JAVA开发手册>里面写超过 ...

  6. django 多对多表的创建,级联删除,手动创建第三张表

    创建一张作者表,author,创建外键与book表,多对多关系 ,外键字段放在那张表都可以, class Author(models.Model):name = models.CharField(ma ...

  7. 涨知识了!阿里规定超过三张表禁止join,为啥?

    点击上方"菜鸟学Python",选择"星标"公众号 重磅干货,第一时间送达 作者:e71hao blog.itpub.net/30393770/viewspac ...

  8. python做值班表预测_Django model一张表中两个字段设置外键参考另一张表两个字段...

    class products(models.Model): MODE_CHOICES=(('week','周'),('day','日')) productname=models.CharField(m ...

  9. sql 两张表的相同字段中刷选出不同数据

    我们在业务逻辑中,经常会涉及两张表之间的数据比较, 其中涉及到某张表中独一份的数据,如下 1 两张表中相同字段name , 查询出在表a存在而表b中不存在的数据,并去重 方法一: SELECT DIS ...

最新文章

  1. AI做不了“真”3D图像?试试Google的新生成模型
  2. GNU make manual 翻译( 一百二十一)
  3. vs编译protobuf 3.0.0
  4. 音视频技术开发周刊 | 150
  5. 数学--数论--积性函数(初步)
  6. leetcode441. 排列硬币(二分查找)
  7. Python 3.8.3 发布
  8. VC Studio集成开发环境下编译Apache--jin点滴实验手记
  9. 从html提取swf文件,Sothink SWF Catcher(SWF文件捕捉提取工具)V2.7 正式版
  10. jdk官网下载账号登陆
  11. PowerDesigner 生成数据字典
  12. Xiaojie雷达之路---车载雷达信号处理流程
  13. 使用DataV制作实时销售数据可视化大屏
  14. 2021年特种设备安全管理(全国特种设备安全管理人员模拟考试题库一)安考星
  15. sklearn中精确率、召回率及F1值得micro,macro及weighted算法
  16. Reversible Data Hiding in Encrypted Images by Reversible Image Transformation
  17. 头条白板面试_让我们谈谈白板面试和可能的替代方法
  18. C语⾔核⼼基础知识之printf
  19. 2018-11-5-win10-uwp-异步转同步
  20. Keras之Conv2D

热门文章

  1. 交换机是如何对数据包打标签去标签的_条形码软件如何在标签纸上套打可变条码...
  2. ETL异构数据源Datax_MySQL同步Oracle(全量)_07
  3. 权限管理快速入门_01
  4. 一个简洁实用的后台管理系统AWESOME
  5. vue 判断同一数组内的值是否一直_vue一些笔记
  6. 计算机如何玩二十四点游戏,数学二十四点游戏有什么技巧吗?
  7. python定期自动运行_干货分享 | 适合 Python 入门的 8 款强大工具,不会就你还不知道吧!...
  8. pythonxml库_对python 生成拼接xml报文的示例详解
  9. 分享按钮 html代码,超简洁微博分享按钮代码
  10. ckeditor java 上传_java使用CKEditor实现图片上传功能