消息重复的处理---幂等性浅谈
概述
幂等性原本是数学上的概念,即使公式: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
消息重复的处理---幂等性浅谈相关推荐
- linux消息队列go的channel,浅谈Go Channel 高级实践
channel 是 golang 里相当有趣的一个功能,在我使用 golang 编码的经验里,大部分事件都会是在享受 channel 和 goroutine 配合的乐趣.所以本文主要介绍 channe ...
- 【浅谈电商】如何防止重复支付
[浅谈电商]如何防止重复支付 一.前言 最近正在做电商相关的项目,整理一下解决方案并帮助自己巩固知识点,此方案是结合了目前的业务环境,若有更好的解决的方式很高兴与大家一起讨论. 二.支付流程 要想知道 ...
- 浅谈消息队列及常见的分布式消息队列中间件
背景 分布式消息队列中间件是是大型分布式系统不可缺少的中间件,通过消息队列,应用程序可以在不知道彼此位置的情况下独立处理消息,或者在处理消息前不需要等待接收此消息.所以消息队列主要解决应用耦合.异步消 ...
- python 字典键值重复_浅谈python字典多键值及重复键值的使用
在python中使用字典,格式如下: dict={ key1:value1 , key2;value2 ...} 在实际访问字典值时的使用格式如下: dict[key] 多键值 字典的多键值形式如下: ...
- 如何保证消息不被重复消费啊(如何保证消息消费时的幂等性)?
1.面试题 如何保证消息不被重复消费啊(如何保证消息消费时的幂等性)? 2.面试官心里分析 其实这个很常见的一个问题,这俩问题基本可以连起来问.既然是消费消息,那肯定要考虑考虑会不会重复消费?能不能避 ...
- 浅谈 RocketMQ、Kafka、Pulsar 的事务消息
作者:ruoyuliu刘若愚,腾讯 WXG 后台开发工程师 导语 事务是一个程序执行单元,里面的所有操作要么全部执行成功,要么全部执行失败.RocketMQ.Kafka 和 Pulsar 都是当今业界 ...
- 浅谈iOS和Android后台实时消息推送的原理和区别
http://www.52im.net/thread-286-1-1.html 前言 iOS和Android上的实时消息推送差异很大,往小了说是技术实现的差异,往大了说是系统实现理念的不同.实时消息推 ...
- 浅谈大数据中的 2PC、3PC、Paxos、Raft、ZAB
一致性 简述 一致性,是指对每个节点一个数据的更新,整个集群都知道更新,并且是一致的.假设一个具有N个节点的分布式系统,当其满足以下条件时,我们说这个系统满足一致性: 全认同: 所有N个节点都认同一个 ...
- 【kafka】浅谈Kafka的多线程消费的设计
1.概述 转载:浅谈Kafka的多线程消费的设计 看原文去... 一.前言 跟RabbitMQ相比,Kafka的分区机制(Partition)使其支持对同一个"队列"分片并行读取, ...
最新文章
- Python向来以慢著称,为啥Instagram却唯独钟爱它?
- SQL Server procedure
- Tensorflow 2.3 GPU安装
- 唯品会在 Flink 容器化与平台化上的建设实践
- Java:ChronicleMap第3部分,快速微服务
- matlab 控制声卡,请问高手关于matlab控制声卡输出的问题
- lateX 编译中文_LaTeX | 为学术论文排版而生【入门篇】
- IT的2017,面临数字生态系统新挑战,该怎么办?
- 深度学习 + OpenCV,Python实现实时视频目标检测
- [LeetCode][easy]Reformat The String
- ubuntu14.04人脸相似度dlib模块和skimage模块安装
- 《软件开发的形式化方法-古天龙》笔记(1)
- Percona XtraBackup User Manual
- SetProcessWorkingSetSize 和内存释放
- 3-19JavaScript
- java项目调用dll类库报错“出现%1 不是有效的 Win32 应用程序”
- 2019世界机器人大会
- 运筹说 第47期 | 算法介绍之目标规划
- 我们平常习惯讲的手机容量-运行内存(RAM)和机身内存(ROM)的理解
- 彻底解决烦人的win10更新
热门文章
- java记录-String、StringBuilder和StringBuffer
- 计算机内存的安装方法,电脑内存条安装教程_电脑内存条安装注意事项
- c语言程序24转换12时间,C语言将24小时制转换为12小时制的方法
- 什么是面向对象?你是怎么理解面向对象的?为什么要用面向对象?用面向对象有什么好处?
- python key=lambda函数_使用’key’和lambda表达式的python max函数
- 慢聊Go之Go常见的Web 开发框架
- LabWindows_CVI测试技术及工程应用_学习笔记1(构建一个简单的程序)
- 【学术方法 | 文献阅读】How to Read Papers
- [Validation set: 'activiti-executable-process' | Problem: 'activiti-exclusive-gateway-condition-not-
- 计算机键盘键盘一个按键坏了,我的世界:如果键盘坏掉一个键,六种情况,哪个会影响你玩MC?...