浅谈网络中接口幂等性设计问题
所谓幂等性设计,就是说,一次和多次请求某一个资源应该具有同样的副作用。用数学的语言来表达就是:f(x) = f(f(x))。
在数学里,幂等有两种主要的定义。 在某二元运算下,幂等元素是指被自己重复运算(或对于函数是为复合)的结果等于它自己的元素。
某一元运算为幂等的时,其作用在任一元素两次后会和其作用一次的结果相同。
文章目录
- 一、关于幂等性
- 1、幂等的定义
- 2、幂等的必要性
- 3、幂等性
- 二、对于幂等性的实现
- 1、源头上--控制重复请求(前端防重)
- 2、过程上--过滤重复动作
- 3、结果上--解决重复写风险
一、关于幂等性
1、幂等的定义
所谓幂等性设计,就是说,一次和多次请求某一个资源应该具有同样的副作用。用数学的语言来表达就是:f(x) = f(f(x))。
下面是维基百科中对于幂等的定义:
在数学里,幂等有两种主要的定义。 在某二元运算下,幂等元素是指被自己重复运算(或对于函数是为复合)的结果等于它自己的元素。
某一元运算为幂等的时,其作用在任一元素两次后会和其作用一次的结果相同。
百度百科上是这么说的:
在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。
幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。
简而言之,幂等是指:多次调用方法或者接口不会改变业务状态,可以保证重复调用的结果和单次调用的结果一致。
2、幂等的必要性
根据上面对幂等性的定义我们得知:产生重复数据或数据不一致,这个绝大部分是由于发生了重复请求。
这里的重复请求是指同一个请求在一些情况下被多次发起。
在接口调用时一般情况下都能正常返回信息不会重复提交,不过在遇见以下情况时可能就会出现问题,如:
- 微服务架构下,不同微服务间会有大量的基于 http,rpc 或者 mq 消息的网络通信。如果超时了,微服务框架会进行重试;
- 用户交互的时候多次点击,无意地触发多笔交易;
- MQ消息中间件,消息重复消费;
- 第三方平台的接口(如:支付成功回调接口),因为异常也会导致多次异步回调;
- 其他中间件/应用服务根据自身的特性,也有可能进行重试。
举几个支付时的例子:
- 订单创建接口,第一次调用超时了,然后调用方重试了一次。是否会多创建一笔订单?
- 订单创建时,我们需要去扣减库存,这时接口发生了超时,调用方重试了一次。是否会多扣一次库存?
- 当这笔订单开始支付,在支付请求发出之后,在服务端发生了扣钱操作,接口响应超时了,调用方重试了一次。是否会多扣一次钱?
因为系统超时,而调用户方重试一下,会给我们的系统带来不一致的副作用。
3、幂等性
幂等性主要保证多次调用对资源的影响是一致的。其本质是通过唯一标识,标记同一操作的方式,来消除多次执行的副作用。
下一用 SQL DML 命令来理解幂等性操作:
- 查询(SELECT):查询语句不会对数据产生任何变化,天然具备幂等性;
- 新增(INSERT):带有唯一索引,重复插入会导致后续执行失败,具有幂等性;不带有唯一索引,多次插入会导致数据重复,不具有幂等性;
- 修改(UPDATE):直接赋值(score = 1),不管执行多少次 score 都一样,具备幂等性;计算赋值(score = score + 1),每次操作 score 数据都不一样,不具备幂等性;
- 删除(DELETE):绝对值删除(DELETE FROM … WHERE …),重复多次结果一样,具备幂等性;相对值删除(DELETE top(3) FROM …),重复多次结果不一致,不具备幂等性。
二、对于幂等性的实现
总的来说,我们解决幂等性问题就是要控制对资源的写操作,因此我们可以通过控制重复请求、过滤重复动作、解决重复写风险三种方式分别在源头、过程以及结果上对幂等性问题进行分析解决。
1、源头上–控制重复请求(前端防重)
通过前端防重保证幂等是最简单的实现方式,前端相关属性和JS代码即可完成设置。可靠性并不好,有经验的人员可以通过工具跳过页面仍能重复提交。主要适用于表单重复提交或按钮重复点击。
主要解决方案**:**
- 控制操作次数,例如:提交按钮仅可操作一次(提交动作后按钮置灰)
- 及时重定向,例如:下单/支付成功后跳转到成功提示页面,这样消除了浏览器前进或后退造成的重复提交问题。
2、过程上–过滤重复动作
# PRG 模式(前端)
PRG 模式即 POST-REDIRECT-GET。当用户进行表单提交时,会重定向到另外一个提交成功页面,而不是停留在原先的表单页面。这样就避免了用户刷新导致重复提交。同时防止了通过浏览器按钮前进/后退导致表单重复提交。 是一种比较常见的前端防重策略。
# 分布式锁
利用 Redis 记录当前处理的业务标识,当检测到没有此任务在处理中,就进入处理,否则判为重复请求,可做过滤处理。
订单发起支付时,支付系统先去 Redis 中查询是否存在该订单号的 Key。若不存在,则在 Redis 中新增这个Key。
接着查询订单是否已支付,若未支付,则支付完成后删除该订单的Key。
通过Redis做分布式锁,只有当一个请求执行完成后,才能执行下个请求。
# Token 机制实现
通过 Token 机制实现接口的幂等性,这是一种比较通用性的实现方法。
具体流程步骤:
- 客户端先发送一个请求去获取 Token,服务端会生成一个全局唯一的 ID 作为 Token 保存在 Redis 中,同时把这个 ID 返回给客户端;
- 客户端第二次调用业务请求的时候必须携带这个 Token;
- 服务端校验这个 Token,如果校验成功,则执行业务,并删除 Redis 中的 Token;
- 如果校验失败,说明 Redis 中已经没有对应的 Token,表示重复操作,直接返回指定的结果给客户端。
# 防重表
对于防止数据重复提交,还有一种解决方案就是通过防重表实现。防重表的实现思路也非常简单。首先创建一张表 作为防重表,同时在该表中建立一个或多个字段的唯一索引作为防重字段,用于保证并发情况下,数据只有一条。 在向业务表中插入数据之前先向防重表插入,如果插入失败则表示是重复数据。
- 对于防重表的解决方案,可能有人会说为什么不使用悲观锁。悲观锁在使用的过程中也是会发生死锁的。悲观锁是 通过锁表的方式实现的。 假设现在一个用户 A 访问表 A(锁住了表 A),然后试图访问表 B;
- 另一个用户 B 访问表 B(锁住了表 B),然后试图访问表 A。 这时对于用户 A 来说,由于表 B 已经被用户 B 锁住了,所以用户 A 必须等到用户 B 释放表 B 才能访问。 同时对于用户 B 来说,由于表 A 已经被用户 A 锁住了,所以用户 B 必须等到用户 A 释放表 A 才 能访问。此时死锁就已经产生了。
3、结果上–解决重复写风险
常见的方式有:悲观锁(for update)、乐观锁、唯一约束。
# 悲观锁
假设每一次拿数据,都有认为会被修改,所以给数据库的行或表上锁。
当数据库执行 select for update
时会获取被 select 中的数据行的行锁,因此其他并发执行的 select for update
如果试图选中同一行则会发生排斥(需要等待行锁被释放),因此达到锁的效果。
# 乐观锁
就是很乐观,每次去拿数据的时候都认为别人不会修改。更新时如果 version 变化了,更新不会成功。
缺点:就是在操作业务前,需要先查询出当前的 version 版本。
另外,还存在一种:状态机控制
例如:支付状态流转流程:待支付 -> 支付中 -> 已支付
具有一定要的前置要求的,严格来讲,也属于乐观锁的一种。
# 唯一约束
这种实现方式是利用 mysql 唯一索引的特性。
- 因为表中某个字段带有唯一索引,如果插入成功,证明表中没有这次请求的信息,则执行后续的业务逻辑;
- 如果插入失败,则代表已经执行过当前请求,直接返回。
相关文章:
浅谈网络中接口幂等性设计问题
所谓幂等性设计,就是说,一次和多次请求某一个资源应该具有同样的副作用。用数学的语言来表达就是:f(x) f(f(x))。 在数学里,幂等有两种主要的定义。 在某二元运算下,幂等元素是指被自己重复运算(或对于函数…...
《C Primer Plus》第13章复习题与编程练习
《C Primer Plus》第13章复习题与编程练习复习题1. 下面的程序有什么问题?2. 下面的程序完成什么任务?(假设在命令行环境中运行)3. 假设程序中有下列语句:4. 编写一个程序,不接受任何命令行参数或接受一个命…...
计算机SCI论文应该怎么作图? - 易智编译EaseEditing
计算机SCI论文,作图时要注意以下几个方面的问题: 1.图片的格式要tiff或者eps; 2.文件大小不能超过10M; 3.长和宽也给出了具体要求; 4.色彩模式要RGB或者灰度图; 5.文中的文字字体和大小; …...
【一】kubernetes集群部署
一、docker环境搭建 1、移除以前docker相关包 sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine2、配置yam源 sudo yum install -y yum-utilssudo yum-config-manager --ad…...
Docker安装Redis
一、拉取镜像 命令::docker pull <镜像名称>:<版本号> docker pull redis 二:Docker挂载配置文件 挂载:即将宿主的文件和容器内部目录相关联,相互绑定,在宿主机内修改文件的话也随之修改容…...
在shell中执行一条可执行程序(./a.out) 系统执行的过程
目录 系统调度过程 用户空间角度: 内核角度 1、调用fork创建一个新进程 2、使用_fo_fork创建新进程 3、父进程调用wake_up_new_task尝试唤醒新进程 4、CPU选择一个合适的进程来运行; 5、运行新进程 6、实现负载均衡 系统调度过程 分析在命令行…...
【ArcGIS Pro二次开发】(10):属性表字段(field)的修改
在ArcGIS Pro中,经常会遇到用字段计算器对要素的属性表进行计算。下面以一个例子演示如何在ArcGIS Pro SDK二次开发中实现。 一、要实现的功能 如上图所示的要素图层,要实现如下功能: 当字段【市级行政区】的值为【泉州市】时,将…...
数据结构与算法—散列表
目录 散列表 散列函数 散列冲突解决 1、开放寻址法 1.1 线性探测 1.2 二次探测 1.3 双重散列 2、链表法 使用场景 单词查找 散列表与链表的结合使用LRU 散列表总结 散列表实例 散列表 Word 单词拼写功能,如何实现的?散列表(Has…...
计算机网络笔记、面试八股(一)—— TCP/IP网络模型
本章目录1. TCP/IP网络模型1.1 应用层1.1.1 应用层作用1.1.2 应用层有哪些常用协议1.2 运输层1.2.1 TCP与UDP的区别1.2.2 分块传输1.2.3 端口1.3 网络层1.3.1 IP报文1.3.2 IP地址1.3.3 网络号和主机号的获得1.3.4 子网掩码的获得1.3.5 路由1.3.6 IP地址与MAC地址的区别1.3.7 AR…...
Servlet笔记(18):国际化
三个概念 国际化: 意义着一个网站提供不同版本的翻译成访问者的语言或国籍的内容。本地化: 意味着向网站添加资源,以使其适应特定的地理或文化区域。区域设置: 针对某个国家的某个地区的设置。 Servlet可以根据请求者的区域设置…...
kibana搭建(windowslinux)
1.说明 搭建kibana方便查询es库,本文分别对windows和linux版本进行安装,因为es集群版本是7.4.1,所以配套的kibana也是选择相同版本 2.下载 https://artifacts.elastic.co/downloads/kibana/kibana-7.4.1-windows-x86_64.zip https://artifact…...
(pytorch进阶之路)Informer
论文:Informer: Beyond Efficient Transformer for Long Sequence Time-Series Forecasting (AAAI’21 Best Paper) 看了一下以前的论文学习学习,我也是重应用吧,所以代码部分会比较多,理论部分就一笔带过吧 论文作者也很良心的…...
关键词聚类和凸现分析-实战1——亚急性甲状腺炎的
审稿人问题第8页第26行-请指出#是什么意思,并解释为什么亚急性甲状腺炎在这里被列为#8。我认为在搜索亚急性甲状腺炎相关文章时,关键词共现分析应该提供关键词共现的数据。这些结果的实际用途是什么?亚急性甲状腺炎是一种较为罕见但重要的甲状腺疾病&am…...
二叉树——二叉搜索树中的众数
二叉搜索树中的众数 链接 给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。 如果树中有不止一个众数,可以按 任意顺序 返回。 假定…...
安装_配置参数解读_集群安装配置_启动选举_搭建启停脚本---大数据之ZooKeeper工作笔记004
这里首先下载zookeeper安装包,可以看到官网地址 找到download 点击下载 找到老一点的,我们找3.5.7 in the archive 点击 然后这里找到3.5.7这一个 然后下载这个-bin.tar.gz这个...
RTMP的工作原理及优缺点
一.什么是RTMP?RTMP(Real-Time Messaging Protocol,实时消息传输协议)是一种用于低延迟、实时音视频和数据传输的双向互联网通信协议,由Macromedia(后被Adobe收购)开发。RTMP的工作原理是&#…...
【数据结构与算法】——第八章:排序
文章目录1、基本概念1.1 什么是排序1.2 排序算法的稳定性1.3 排序算法的分类1.4 内排序的方法2、插入排序2.1 直接插入排序2.2 直接插入排序2.3 希尔排序3、交换排序3.1 冒泡排序3.2 快速排序4、选择排序4.1 简单选择排序4.2 树形选择排序4.3 堆排序4.4 二路归并排序5、基数排序…...
在linux中web服务器的搭建与配置
以下涉及到的linux命令大全查阅 https://www.runoob.com/linux/linux-command-manual.htmlvim命令查阅 https://www.runoob.com/linux/linux-vim.htmlscp命令https://www.runoob.com/linux/linux-comm-scp.html首先要有一个请求的服务地址用ssh 进入到linux系统中ssh 请求的服务…...
《Python机器学习》基础代码2
👂 逝年 - 夏小虎 - 单曲 - 网易云音乐 目录 👊Matplotlib综合应用:空气质量监测数据的图形化展示 🌼1,AQI时序变化特点 🌼2,AQI分布特征 相关性分析 🌼3,优化图形…...
如何基于MLServer构建Python机器学习服务
文章目录前言一、数据集二、训练 Scikit-learn 模型三、基于MLSever构建Scikit-learn服务四、测试模型五、训练 XGBoost 模型六、服务多个模型七、测试多个模型的准确性总结参考前言 在过去我们训练模型,往往通过编写flask代码或者容器化我们的模型并在docker中运行…...
9.1 IGMPv1实验
9.4.1 IGMPv1 实验目的 熟悉IGMPv1的应用场景掌握IGMPv1的配置方法实验拓扑 实验拓扑如图9-7所示: 图9-7:IGMPv1 实验步骤 (1)配置IP地址 MCS1的配置 MCS1的IP地址配置如图9-8所示: 图9-8:MCS1的配置 …...
软考高级系统分析师系列论文之十:论实时控制系统与企业信息系统的集成在通信业应用
软考高级系统分析师系列论文之十:论实时控制系统与企业信息系统的集成在通信业应用 一、摘要二、正文三、总结一、摘要 近年来,在应用需求的强大驱动下,我国通信业有了长足的进步。现有通信行业中的许多企业单位,如电信公司或移动集团,其信息系统的主要特征之一是对线路的…...
NIO与零拷贝
目录 一、零拷贝的基本介绍 二、传统IO数据读写的劣势 三、mmap优化 四、sendFile优化 五、 mmap 和 sendFile 的区别 六、零拷贝实战 6.1 传统IO 6.2 NIO中的零拷贝 6.3 运行结果 一、零拷贝的基本介绍 零拷贝是网络编程的关键,很多性能优化都离不开。 在…...
【PAT甲级题解记录】1151 LCA in a Binary Tree (30 分)
【PAT甲级题解记录】1151 LCA in a Binary Tree (30 分) 前言 Problem:1151 LCA in a Binary Tree (30 分) Tags:树的遍历 并查集 LCA Difficulty:剧情模式 想流点汗 想流点血 死而无憾 Address:1151 LCA in a Binary Tree (30 分…...
Android 获取手机语言环境 区分简体和繁体,香港,澳门,台湾繁体
安卓和IOS 系统语言都是准守:ISO 639 ISO 代码表IOS:plus.os.language ios正常,安卓下简体和繁体语言,都是zh安卓获取系统语言方法:Locale.getDefault().language手机切换到繁体(台湾,香港&…...
一文搞懂Python时间序列
Python时间序列1. datetime模块1.1 datetime对象1.2 字符串和datatime的相互转换2. 时间序列基础3. 重采样及频率转换4. 时间序列可视化5. 窗口函数5.1 移动窗口函数5.2 指数加权函数5.3 二元移动窗口函数时间序列(Time Series)是一种重要的结构化数据形…...
GeoServer发布数据进阶
GeoServer发布数据进阶 GeoServer介绍 GeoServer是用于共享地理空间数据的开源服务器。 它专为交互操作性而设计,使用开放标准发布来自任何主要空间数据源的数据。 GeoServer实现了行业标准的 OGC 协议,例如网络要素服务 (WFS)…...
Docker离线部署
Docker离线部署 目录 1、需求说明 2、下载docker安装包 3、上传docker安装包 4、解压docker安装包 5、解压的docker文件夹全部移动至/usr/bin目录 6、将docker注册为系统服务 7、重启生效 8、设置开机自启 9、查看docker版本信息 1、需求说明 大部份公司为了服务安全…...
《数据库系统概论》学习笔记——第七章 数据库设计
教材为数据库系统概论第五版(王珊) 这一章概念比较多。最重点就是7.4节。 7.1 数据库设计概述 数据库设计定义: 数据库设计是指对于一个给定的应用环境,构造(设计)优化的数据库逻辑模式和物理结构&#x…...
【Datawhale图机器学习】半监督节点分类:标签传播和消息传递
半监督节点分类:标签传播和消息传递 半监督节点分类问题的常见解决方法: 特征工程图嵌入表示学习标签传播图神经网络 基于“物以类聚,人以群分”的Homophily假设,讲解了Label Propagation、Relational Classificationÿ…...
优化企业网站/百度一下打开
w10设置文件服务器 内容精选换一换华为云弹性文件服务(Scalable File Service)为用户的弹性云服务器(ECS)提供一个完全托管的共享文件存储,符合标准文件协议(NFS)来自:产品cd /home/ior-master/src/home/OpenMPI/bin/mpirun --allow-run-as-root -machin…...
高端定制网站速度/今天最新新闻
# 本程序要实现的功能是: # 实现学生信息管理系统的增删改查 str_print("name:{}\t,math:{}\t,chinese:{}\t,english:{}\t") grade_list[] while True:print("""**************************欢迎使用【学生信息管理系统】请选择你想要进行的…...
专业网站制作公司名称/百度关键词优化大
<HTML> <HEAD> <TITLE>给数组增加元素</TITLE> </HEAD> <?$Cities[] "<B>北京</B>"; //等同于$Cities[0] "北京"$Cities[] "<B>天津</B>"; //等同于$Cities[1] "天津…...
做网站公司排名/电子商务seo实训总结
原文地址:http://www.twinsenliang.net/skill/20090413.html 早段时间特别的忙,忙到站点一直没有更新;但是这段时间也是偷偷的做了一些的工作,比如对站点的JS进行了压缩,构思labs分站以及聚合分站。 而此段时间最烦的是…...
浙江省两学一做网站/线下宣传渠道和宣传方式
默认的select标签比较难看,UI比较漂亮,如果想要实现UI上的下拉样式,好像必须用js写select,从网上拷贝而且修改了一个下拉框,为了方便以后引用所以记录下来。 /* diy_select */ .diy_select{height:30px;width:90px; po…...
泰安网站制作/常见的营销手段
http://edu.csdn.net/course/detail/2798?locationNum13&fps1...