【从零开始学习重要知识点 | 第一篇】快速了解什么是幂等性以及常见解决方案
前言:
当我们在设计和实现分布式系统时,幂等性是一个非常重要的概念。幂等性可以简单地理解为:对于同一操作,不论执行多少次,产生的影响都是相同的。这个概念在分布式系统中非常重要,因为在这种环境下,由于网络延迟、消息重复等原因,可能会导致同一操作被执行多次。如果操作不具备幂等性,那么这些重复的操作可能会导致系统状态的不一致性、数据的错误或者其他问题。
因此,幂等性是分布式系统中必须要考虑的一个重要问题。在本文中,我们将深入探讨什么是幂等性,为什么它在分布式系统中如此重要,以及如何在设计和实现分布式系统时考虑幂等性。

目录
前言:
什么是幂等性?
常见产生幂等性问题的场景:
常见的幂等解决方案:
1.token机制:
2.分布式锁:
3.MySQL去重表:
总结:
什么是幂等性?
幂等性简单来讲:对于同一操作,不论执行多少次,产生的影响都是相同的。
换一种方式也可以描述为:
对于相同的输入,无论进行多少次重复操作,都应该保持其结果一致。
我们来举一个现实的例子:
当我们在用户网站进行注册的时候,当我们因为系统卡顿而多次点击注册按钮的时候,后端肯定不会在数据库生成多个一样的账号密码,而是只有一个账号密码
在这个场景中去解释幂等性:幂等性就是多次重复调用操作(因为卡顿多次点击注册),对结果只影响一次(最终只注册一个账号密码)
比方说:支付接口没有做幂等性导致重复扣款问题。订单接口没有做幂等性导致的订单重复生成问题。

那么在这种情况下,重复订单的入库就是一个明显的bug。而在保证幂等性的情况下:

因此从后端来看:幂等性就是保证同一个接口在重复接收同一个请求的时候,需要保证效果的唯一性。
常见产生幂等性问题的场景:
- 网络波动引起的重复请求
- 使用了失效或者超时重试机制导致接口被重复调用
- 消息队列中间件的默认重试机制
- 页面重复刷新
- 用户重复点击提交按钮
- 使用浏览器后退按钮重复之前的操作,导致重复提交数据。
前端重复提交,消息重复消费,任务重复执行
常见的幂等解决方案:
1.token机制:
当用户发起请求之前,后端会生成一个键值对存储在redis中,键是当前请求用户的ip+参数,值是token。

当用户向后端发送请求的时候,需要携带token,我们在redis中判断是否存在token,如果存在就删除token并且执行操作,如果不存在token就说明当前已经有相同的请求被执行过。

我们还是用之前的订单接口来举例:

此时的token已经被删除,那么第二次:

我们通过携带token的方式,就保证了这种接口的幂等性。
token机制的缺陷:
-
复杂性和管理成本: 引入 Token 机制会增加系统的复杂性,包括生成、传输、校验和存储 Token 等环节,导致系统开发和维护的成本增加。
-
网络开销: 每次请求都需要携带 Token,并且服务端需要验证 Token 的有效性,这会增加网络开销和服务端的处理负担,降低系统的性能表现。
-
并发冲突: 在高并发场景下,可能会出现多个请求同时携带相同的 Token 并被同时处理的情况,导致操作重复执行或者数据不一致的问题。
-
安全性风险: 如果 Token 不够随机或唯一,可能会受到恶意攻击者的攻击,从而破坏系统的幂等性。此外,泄露 Token 也可能导致安全隐患。
-
存储压力: 如果大量 Token 需要被管理和存储,可能会给系统的存储带来一定的压力,尤其是在高并发场景下。
2.分布式锁:
其实就是基于redis去构造一个分布式锁。具体的构造方法的话,这里就不多介绍了,下面是我之前一篇文章的链接,详细的介绍了如何基于redis构造分布式锁。
【从零开始学习Redis | 第六篇】爆改Setnx实现分布式锁-CSDN博客
https://liyuanxin.blog.csdn.net/article/details/134677169那么通过分布式锁来保证幂等性的逻辑也很简单:
我们把传入的参数和用户id作为键值对来构造出一个键值对。每一次进来都要尝试构造键值对,如果构造成功,就执行业务逻辑代码,如果没有执行成功,就拒绝这次请求
第一次构造成功:
第二次构造失败:

其实就算使用redis中普通的set也是可以的,因为这个本质就是在利用redis中set创建k-v的唯一性。
之所以要用setnx,是要保证redis中不会因为构造分布式锁而留下大量的键值对,使用setnx在限定时间后,键值对就会过期被删除。
需要注意的是:我们这种简单的基于setnx构造的锁,会出现锁误删的问题,在我上面贴出来的文章中也详细介绍了锁误删的情况,大家如果想尝试用Redis来构造分布式锁的话,可以看一看。
这里提到了锁,很多朋友也会关联的想到synchronized,但是synchronized做的是代码块的同步,他会锁住代码块,导致程序并发性能的大大降低。关于这些点我在我上面贴的那篇文章里面也有讲。在这里再贴一下:
【从零开始学习Redis | 第六篇】爆改Setnx实现分布式锁-CSDN博客
https://liyuanxin.blog.csdn.net/article/details/134677169
3.MySQL去重表:
就是在存入MySQL之前,先要检查一下是否有相同数据,如果有相同数据就拒绝插入。
总结:
总之,幂等性在分布式系统和接口设计中扮演着至关重要的角色。通过确保相同操作的重复执行不会产生额外的影响,幂等性能够提升系统的可靠性、稳定性和安全性。然而,实现幂等性并非易事,面临诸多挑战,包括并发冲突、性能开销、安全风险等问题。针对这些挑战,我们可以采取一系列策略和技术手段,例如使用 Token 机制、请求参数校验、消息队列处理等,来确保接口的幂等性。在实际应用中,需要综合考虑系统需求、性能表现和安全要求,选择合适的幂等性解决方案。最终,通过有效地实现幂等性,我们能够构建更加稳健、可靠的系统,为用户提供更好的体验和保障数据的一致性。
如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!

相关文章:
【从零开始学习重要知识点 | 第一篇】快速了解什么是幂等性以及常见解决方案
前言: 当我们在设计和实现分布式系统时,幂等性是一个非常重要的概念。幂等性可以简单地理解为:对于同一操作,不论执行多少次,产生的影响都是相同的。这个概念在分布式系统中非常重要,因为在这种环境下&…...
Jvm之内存泄漏
1 内存溢出 1.1 概念 java.lang.OutOfMemoryError,是指程序在申请内存时,没有足够的内存空间供其使用,出现OutOfMemoryError。产生该错误的原因主要包括:JVM内存过小。程序不严密,产生了过多的垃圾。 程序体现: 内…...
尚硅谷webpack5笔记2
Loader 原理 loader 概念 帮助 webpack 将不同类型的文件转换为 webpack 可识别的模块。 loader 执行顺序 分类pre: 前置 loadernormal: 普通 loaderinline: 内联 loaderpost: 后置 loader执行顺序4 类 loader 的执行优级为:pre > normal > inline > post 。相…...
笔记本Win 10系统查看电池健康状况
博主最近换了个笔记本电池,之前的电池容量明显变小了很多,而且出现了轻微鼓包的情况。所以用gpt问了一下怎么用系统的方法查看电池情况。 在Windows 10系统中,您可以通过以下步骤来查看笔记本电脑电池的健康状况: 打开命令提示符&…...
算法--动态规划(线性DP、区间DP)
这里写目录标题 tip数组下标从0开始还是从1开始 数学三角形介绍算法思想例题代码 最长上升子序列介绍算法思想例题代码 最长公共子序列介绍算法思想例题代码 tip 数组下标从0开始还是从1开始 如果代码中涉及到数组下标为i-1(有时候哪怕不是同一个数组也符合情况&am…...
【ArcGIS】统计格网中不同土地利用类型占比
基于ArcGIS统计格网中不同土地利用类型占比 数据准备ArcGIS操作步骤1、创建渔网(Create Fishnet)2、建立唯一标识3、选择格网4、提取不同类别土地利用类型5、各类用地面积计算 参考另:可能出现的问题总结Q1:ArcGIS获取唯一值&…...
算法竞赛实用板子
一、声明 自用版参考acwing,致力于实用、好用,板子中有个人理解,持续更新。 二、开板 1.快排 void quick_sort(int q[],int l,int r) {if(l>r)return; //出口int il-1,jr1,xq[lr>>1]; //分治方法while(i<j){do i;w…...
RPA中国 x UiPath | 第六届RPA极客挑战赛,3月16日上海开赛!
随着人工智能技术的不断进步以及数字化转型的深入,企业对于高效、精准、自动化的业务流程需求日益迫切。RPA技术作为连接人类工作与机器操作的桥梁,正逐渐从规则驱动发展为智能决策的助手。 由RPA中国联合UiPath共同主办的【第六届RPA极客挑战赛】将于2…...
算法打卡day5|哈希表篇01|Leetcode 242.有效的字母异位词 、19.删除链表的倒数第N个节点、202. 快乐数、1. 两数之和
哈希表基础知识 哈希表 哈希表关键码就是数组的索引下标,然后通过下标直接访问数组中的元素;数组就是哈希表的一种 一般哈希表都是用来快速判断一个元素是否出现集合里。例如要查询一个名字是否在班级里: 要枚举的话时间复杂度是O(n)&…...
『python爬虫』xpath变化导致无法找到指定元素(持续更新中~)
目录 xpath变化的原因1. 语言设置2. 窗口大小n. 待添加~总结 欢迎关注 『python爬虫』 专栏,持续更新中 欢迎关注 『python爬虫』 专栏,持续更新中 xpath变化的原因 XPath 可能会出现变化的原因有很多,以下是一些常见的情况: 网页…...
人大金仓数据库Kingbase服务SQL基础操作手册
1 kingbase服务 1.1 查看kingbase数据库服务进程 ps -ef|grep kingbase1.2 命令启动kingbase数据库服务 # /opt/Kingbase/ES/V8 为金仓安装目录 # /opt/Kingbase/ES/V8/data 为金仓数据目录 # sys_ctl是数据库服务器启停命令,通过-D选项来来指定数据库数据目录 #…...
赎金信00
题目链接 赎金信 题目描述 注意点 magazine中的每个字符只能在ransomNote中使用一次ransomNote和magazine由小写英文字母组成 解答思路 因为ransomNote和magazine由小写英文字母组成,所以使用大小为26的数组存储magazine中a~z对应出现的次数,ransom…...
如何运行github上的项目
为了讲明白这个过程,特意做了一个相当来说比较好读懂的原理图,希望和我一样初学的小伙伴也能很快上手哈😊 在Github中找到想要部署的项目,这里以BartoszJarocki/CV(线上简历📄)项目为例 先从头…...
机器学习-02-机器学习算法分类以及在各行各业的应用
总结 本系列是机器学习课程的第02篇,主要介绍机器学习算法分类以及在各行各业的应用 本门课程的目标 完成一个特定行业的算法应用全过程: 定义问题(Problem Definition) -> 数据收集(Data Collection) -> 数据分割(Data…...
Java项目学习
一、Java项目学习 1.1 瑞吉外卖(项目提供的资料没笔记) 视频资源:https://www.bilibili.com/video/BV13a411q753/?p1 本人git项目地址:https://gitee.com/xx-xuxin/reggie_take_out.git 瑞吉外卖Day01~Day06没讲的功能(全功能实现…...
npm run dev和npm run serve两个命令的区别
npm run dev和npm run serve两个命令的区别 前端开发过程中运行Vue项目的时候,有时候使用npm run serve命令可以启动项目,有时候却会报错;有时候使用npm run dev命令可以启动项目,有时候却也会报错。是什么原因造成这种情况呢&am…...
ui设计:利用即使设计设计出漂亮样式
目录 一、基本操作 二、具体介绍 6-1 填充图片 6-2 填充色 6-3 图标 右边栏基础设置 右边栏导出编辑 一、基本操作 二、具体介绍 6-1 填充图片 选择其一图片填充 6-2 填充色 6-3 图标 右边栏基础设置 右边栏导出...
[unity]lua热更新——个人复习笔记【侵删/有不足之处欢迎斧正】
一、AssetBundle AB包是特定于平台的资产压缩包,类似于压缩文件 相对于RESOURCES下的资源,AB包更加灵活轻量化,用于减小包体大小和热更新 可以在unity2019环境中直接下载Asset Bundle Browser 可以在其中设置关联 AB包生成的文件 AB包文件…...
Springboot日常总结-@RestController和@Controller的区别
RestController和 Controlle是两种不同的控制器实现,它们的主要区别在于如何处理返回的数据和是否支持跳转到视图页面。 Controller 是一个基本的控制器注解,它允许你将一个类标记为一个Spring MVC控制器处理器。使用 Controller 的类中的方法可以直接返…...
MongoDB之客户端工具与核心概念及基本类型篇
MongoDB之客户端工具与核心概念及基本类型篇 文章目录 MongoDB之客户端工具与核心概念及基本类型篇1. MongoDB是什么?1. 关于MongoDB2. 相关客户端工具1. MongoDB Compass2. Studio 3T3. Navicat for MongoDB4. NoSQL Manager for MongoDB Professional 2.MongoDB相关概念2.1 …...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)
在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...
DiscuzX3.5发帖json api
参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...
[USACO23FEB] Bakery S
题目描述 Bessie 开了一家面包店! 在她的面包店里,Bessie 有一个烤箱,可以在 t C t_C tC 的时间内生产一块饼干或在 t M t_M tM 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC,tM≤109)。由于空间…...
