概述

幂等性原本是数学上的概念,即使公式:f(x)=f(f(x)) 能够成立的数学性质。用在编程领域,则意为对同一个系统,使用同样的条件,一次请求和重复的多次请求对系统资源的影响是一致的

幂等性是分布式系统设计中十分重要的概念,具有这一性质的接口在设计时总是秉持这样的一种理念:调用接口发生异常并且重复尝试时,总是会造成系统所无法承受的损失,所以必须阻止这种现象的发生

幂等有两个维度:一是空间维度上的幂等,即幂等对象的范围,是个人还是机构,是某一次交易还是某种类型的交易...二是时间维度上的幂等,即幂等的保证时间,是几秒、几分钟还是永久性的...

不同的需求,会有不一样的解决方案,难度和成本也不一样。

幂等性适用领域

试想这样的一种场景:在电商平台上支付后,因为网络原因导致系统提示你支付失败,于是你又重新付款了一次,等完成后检查网银发现被系统扣了两次款,这是一种什么样的体验?

造成上述问题的原因可能有很多,比如第一次付款时实际支付成功,但是信息返回时网络中断导致系统误判;又比如第一次付款的确失败了,但第二次付款时发生意外,导致支付请求被重复发送等等。在一次支付的过程中,每个环节都有可能会发生问题,我们要如何规避这类问题引发的分险?

幂等性是解决这类问题的方案之一,所以在电商,银行,互联网金融等对数据准确性要求很高的领域中,这一特性具有十分重要的地位。

幂等的常用思路

1. MVCC:####

多版本并发控制,乐观锁的一种实现,在数据更新时需要去比较持有数据的版本号,版本号不一致的操作无法成功。例如博客点赞次数自动+1的接口:

public boolean addCount(Long id, Long version);
update blogTable set count= count+1,version=version+1 where id=321 and version=123

每一个version只有一次执行成功的机会,一旦失败必须重新获取。

2. 去重表:####

利用数据库表单的特性来实现幂等,常用的一个思路是在表上构建唯一性索引,保证某一类数据一旦执行完毕,后续同样的请求再也无法成功写入。

例子还是上述的博客点赞问题,要想防止一个人重复点赞,可以设计一张表,将博客id与用户id绑定建立唯一索引,每当用户点赞时就往表中写入一条数据,这样重复点赞的数据就无法写入。

或者使用 select + insert 的方式,见https://blog.csdn.net/yinni11/article/details/81149758,那么如何解决消息重复投递的问题?

3. TOKEN机制:####

这种机制就比较重要了,适用范围较广,有多种不同的实现方式。其核心思想是为每一次操作生成一个唯一性的凭证,也就是token。一个token在操作的每一个阶段只有一次执行权,一旦执行成功则保存执行结果。对重复的请求,返回同一个结果。

以电商平台为例子,电商平台上的订单id就是最适合的token。当用户下单时,会经历多个环节,比如生成订单减库存减优惠券等等。

每一个环节执行时都先检测一下该订单id是否已经执行过这一步骤,对未执行的请求,执行操作并缓存结果,而对已经执行过的id,则直接返回之前的执行结果,不做任何操作。这样可以在最大程度上避免操作的重复执行问题,缓存起来的执行结果也能用于事务的控制等。

总结

幂等性是分布式领域的一把利刃,每一个有志与分布式领域的程序员都应该熟悉它的设计思想。

转载于:https://www.jianshu.com/p/475589f5cd7b

消息重复的处理---幂等性浅谈相关推荐

  1. linux消息队列go的channel,浅谈Go Channel 高级实践

    channel 是 golang 里相当有趣的一个功能,在我使用 golang 编码的经验里,大部分事件都会是在享受 channel 和 goroutine 配合的乐趣.所以本文主要介绍 channe ...

  2. 【浅谈电商】如何防止重复支付

    [浅谈电商]如何防止重复支付 一.前言 最近正在做电商相关的项目,整理一下解决方案并帮助自己巩固知识点,此方案是结合了目前的业务环境,若有更好的解决的方式很高兴与大家一起讨论. 二.支付流程 要想知道 ...

  3. 浅谈消息队列及常见的分布式消息队列中间件

    背景 分布式消息队列中间件是是大型分布式系统不可缺少的中间件,通过消息队列,应用程序可以在不知道彼此位置的情况下独立处理消息,或者在处理消息前不需要等待接收此消息.所以消息队列主要解决应用耦合.异步消 ...

  4. python 字典键值重复_浅谈python字典多键值及重复键值的使用

    在python中使用字典,格式如下: dict={ key1:value1 , key2;value2 ...} 在实际访问字典值时的使用格式如下: dict[key] 多键值 字典的多键值形式如下: ...

  5. 如何保证消息不被重复消费啊(如何保证消息消费时的幂等性)?

    1.面试题 如何保证消息不被重复消费啊(如何保证消息消费时的幂等性)? 2.面试官心里分析 其实这个很常见的一个问题,这俩问题基本可以连起来问.既然是消费消息,那肯定要考虑考虑会不会重复消费?能不能避 ...

  6. 浅谈 RocketMQ、Kafka、Pulsar 的事务消息

    作者:ruoyuliu刘若愚,腾讯 WXG 后台开发工程师 导语 事务是一个程序执行单元,里面的所有操作要么全部执行成功,要么全部执行失败.RocketMQ.Kafka 和 Pulsar 都是当今业界 ...

  7. 浅谈iOS和Android后台实时消息推送的原理和区别

    http://www.52im.net/thread-286-1-1.html 前言 iOS和Android上的实时消息推送差异很大,往小了说是技术实现的差异,往大了说是系统实现理念的不同.实时消息推 ...

  8. 浅谈大数据中的 2PC、3PC、Paxos、Raft、ZAB

    一致性 简述 一致性,是指对每个节点一个数据的更新,整个集群都知道更新,并且是一致的.假设一个具有N个节点的分布式系统,当其满足以下条件时,我们说这个系统满足一致性: 全认同: 所有N个节点都认同一个 ...

  9. 【kafka】浅谈Kafka的多线程消费的设计

    1.概述 转载:浅谈Kafka的多线程消费的设计 看原文去... 一.前言 跟RabbitMQ相比,Kafka的分区机制(Partition)使其支持对同一个"队列"分片并行读取, ...

最新文章

  1. Python向来以慢著称,为啥Instagram却唯独钟爱它?
  2. SQL Server procedure
  3. Tensorflow 2.3 GPU安装
  4. 唯品会在 Flink 容器化与平台化上的建设实践
  5. Java:ChronicleMap第3部分,快速微服务
  6. matlab 控制声卡,请问高手关于matlab控制声卡输出的问题
  7. lateX 编译中文_LaTeX | 为学术论文排版而生【入门篇】
  8. IT的2017,面临数字生态系统新挑战,该怎么办?
  9. 深度学习 + OpenCV,Python实现实时视频目标检测
  10. [LeetCode][easy]Reformat The String
  11. ubuntu14.04人脸相似度dlib模块和skimage模块安装
  12. 《软件开发的形式化方法-古天龙》笔记(1)
  13. Percona XtraBackup User Manual
  14. SetProcessWorkingSetSize 和内存释放
  15. 3-19JavaScript
  16. java项目调用dll类库报错“出现%1 不是有效的 Win32 应用程序”
  17. 2019世界机器人大会
  18. 运筹说 第47期 | 算法介绍之目标规划
  19. 我们平常习惯讲的手机容量-运行内存(RAM)和机身内存(ROM)的理解
  20. 彻底解决烦人的win10更新

热门文章

  1. java记录-String、StringBuilder和StringBuffer
  2. 计算机内存的安装方法,电脑内存条安装教程_电脑内存条安装注意事项
  3. c语言程序24转换12时间,C语言将24小时制转换为12小时制的方法
  4. 什么是面向对象?你是怎么理解面向对象的?为什么要用面向对象?用面向对象有什么好处?
  5. python key=lambda函数_使用’key’和lambda表达式的python max函数
  6. 慢聊Go之Go常见的Web 开发框架
  7. LabWindows_CVI测试技术及工程应用_学习笔记1(构建一个简单的程序)
  8. 【学术方法 | 文献阅读】How to Read Papers
  9. [Validation set: 'activiti-executable-process' | Problem: 'activiti-exclusive-gateway-condition-not-
  10. 计算机键盘键盘一个按键坏了,我的世界:如果键盘坏掉一个键,六种情况,哪个会影响你玩MC?...