接口设计之幂等性设计

2023-11-18

幂等性设计

今天我们来聊聊接口的幂等性设计,所谓幂等,就是任意多次执行所产生的影响均与一次执行的影响相同。 幂等性接口是指可以使用相同参数重复执行,并能获得相同结果的接口。这里就不展开数学中的定义了,有兴趣的可以自行google。

为什么接口需要幂等呢?

我们都知道,作为接口的调用方,对于接口调用的结果,一般会返回成功、失败和超时。对于成功和失败,都是明确的状态,调用放可以根据结果做相应的处理,但是对于超时,由于不确定是否成功请求了,作为调用方来说,所以一般都会选择重试。而重试就会出现定义中描述的多次执行。

可以从下面这个例子中加深一下理解:

创建订单时,需要减库存,如果减库存接口超时了,调用方重新调用一次(无论是否成功的执行了减库存代码),应该要保证不会多减一次库存。

要保证不会多件一次库存,一般有两种做法:

  1. 接口提供方需要提供相应的查询接口。调用方在超时后去查询一下是否成功。是否多扣一次库存掌握在调用方手里。如果接口是提供给第三方使用的,就会存在一定的风险。
  2. 接口支持幂等。这样幂等的保证完全掌握在提供方自己手里,完全不用担心。

全局ID

要让接口支持幂等,要怎么做呢,你可能会想到在减库存之前增加一次查询,已经减过的直接返回不就完事了么?这样确实能达到目的,可是会额外多了一次查询,有没有什么更优的方法呢?

要保证减库存操作的唯一性,可以在接口上多加一个参数,这个参数必须全局唯一,数据库设计表的时候这个字段要加上唯一索引,当多次保存相同数据的时候,数据库就会报错,这就证明了接口已经成功调用过,可以直接返回。

那这个全局ID由谁来分配呢?

  1. 可以创建一个分配中心,由中心统一分配。

    优点:分配ID与业务集群解耦。

    缺点:需要单独维护分配中心,这个分配中心也必须做成高可用集群,增加维护成本。

  2. 集成在业务服务集群

    优点:业务服务集群本来就是高可用的,无需提供额外保证。

    缺点:分配ID与业务耦合(这其实没什么影响),需要保证业务服务集群生成ID的唯一性。

一般来说,后者是比较好的方案,我们只要提供一个能在集群上生成全局唯一ID的算法即可。

除了保证全局唯一,最好具备以下特点(非必须):

  • 递增,起码保证每台机器上的ID递增。(保证数据库性能)
  • 明确的规则,ID的各个位都有具体的定义。(方便追溯)

接下来就来说说现阶段常用的全局ID算法。

UUID

UUID设计的目的就是让分布式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。关于UUID的设计原理可自行Google。

优点:实现简单(大多数编程语言都集成到工具库了),本地生成,性能好,扩展性高,不需要协定。

缺点:无法递增(消耗数据库性能)、UUID过长(消耗存储空间)。

在中小型项目中,UUID会是不错的选择。 为什么这么说呢?面对并发度不高的系统,数据库性能一般不会达到瓶颈,所以说UUID是牺牲数据库性能换取其优点的一种选择。

Snowflake

Snowflake是Twitter 的开源项目,它生成的ID是64bit的正整数,结构如图:

在这里插入图片描述

  • 1bit:固定为0,二进制中最高位为符号位,0为整数,1位负数。所以固定为0表示生成的ID都为正数
  • 41bit:作为毫秒数,大约能用69年。
  • 10bit:作为机器编号(5bit是数据中心ID,5bit为机器ID)。支持1204个实例。
  • 12bit:序列号,一毫秒最多生成2^12=4096个。

优点:递增,且按时间有序。性能高,可根据情况分配bit。

缺点:依赖机器时钟。在分布式系统中,各个机器上的时间不可能完全一样,在同步各机器的时间时,可能会造成重复ID。

在高并发的业务下,Snowflake生成的整数ID的存储和读取性能都要优于UUID。 现阶段国内有很多基于Snowflake算法的特定实现,比如百度的UidGenerator。

关于Redis和MongoDB的设计这里就不展开了。毕竟要强依赖于存储系统,添加了维护成本和风险点。

业务逻辑

在这里插入图片描述

正如我们前面讲过的,要依赖于数据库唯一性约束,当数据库报唯一性冲突时,就说明这个求情已经成功过了,不用再执行,直接返回即可。

HTTP的幂等性

这里给出http请求的幂等性要求:

方法 幂等 描述
GET 天然幂等
HEAD 天然幂等
OPTIONS 天然幂等
DELETE 天然幂等
PUT 天然幂等
POST × 需要支持幂等

对于POST方法,可能会出现多次提交的问题,比如由于网络不好等原因,造成请求超时,这是用户再点一次提交按钮。对此一般的幂等性解决方法如下:

  • 在提交的表单隐藏一个全局ID,这个全局ID需要提前向后端获取,提交的时候把这个ID一起提交过来,按照上图所描述的业务逻辑,来支持幂等。
  • 后端成功以后前端跳转,跳转到GET请求,把刚才提交的数据展示出来。

小结

这篇讲了幂等性设计的要点,并给出了设计方案,大家可根据具体情况选择合适的方案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

接口设计之幂等性设计 的相关文章

  • Java——接口与实现类

    目录 接口 实现接口 常用接口 java util Comparator Arrays sort Object arr Comparator c 常用接口 java lang Comparable Arrays sort Object ar
  • M.2、mSATA、NGFF、miniPCI-e接口引脚定义

    http bbs pceva com cn thread 96050 1 1 html NGFF M 2 以下下简称M2 和SATA Express 以下下简称SATAe 是用以替代当前MiniPCI Express 以下下简称MIni P
  • Java基础--接口(Interface)

    有时必须从几个类中派生出一个子类 继承它们所有的属性和方法 但是 Java不支持多重继承 有个接口 就可以得到多重继承的效果 接口 interface 是抽象方法和常量值的定义的集合 从本质上讲 接口是一种特殊的抽象类 这种抽象类中只包含常
  • JDK1.8接口的默认实现

    很多时候 别人问我接口和类的区别的时候 我都会回答接口里面只能有抽象方法 而不能够有具体方法 但是今天看Mybatis源码的时候 发现了有一段代码是判断接口里面的默认方法的 于是我发现原来对接口的认识太过于肤浅了 JDK1 8之后 在接口里
  • c++STL容器的通用接口(c++STL相关)

    STL容器具有以下一些特点 1 STL主要通过模板方式进行接口编程 2 用了move后原来的左值引用就不存在了 3 对于所有container有begin和end和empty 大多数都有size 除了forward list 大多数都有cl
  • 基于接口设计原则-java

    7种设计坏味道 1 僵化性 很难对系统进行改动 因为每个改动都会迫使许多对系统其他部分的其它改动 2 脆弱性 对系统的改动会导致系统中和改动的地方在概念上无关的许多地方出现问题 3 牢固性 很难解开系统的纠结 使之成为一些可在其他系统中重用
  • v.douyin.com生成制作抖音缩短口令网址php接口方法

    v douyin com是抖音官方的接口 可以制作头条 火山 抖音短视频等官方域名的任意生成接口 可以推广抖音号 第三方网址 头条文章等 效果非常号 这里记录下api接口 纯技术php生成 具体规则可以去抖音的开放平台去申请对应接口 这里用
  • vue中axios的参数位置整理

    每次在进行前后端联调的时候 总是因为参数放不对而影响进度 我人都麻了 真的记不住 还是整理一下以便后续开发 一 vue2和vue3的接口请求头 vue 2 const res await this axios get vue 3 const
  • CAN 为什么需要收发器

    在RTL代码中集成了两个CAN node 打算直接连接将两个node的Rx和Tx对接 发现两个CAN Node无法通信 询问技术支持后才知道必须要收发器 那为什么一定需要收发器呢 除了转换单端的CAN信号用于不同的传输 收发器也会将CANT
  • 调研一台电脑连接两个键盘如何区分遇到的问题及解决方法

    1 查找windows API 手册 调用GetRawInputData函数 可以获得按下的键值VKey以及唯一的句柄hDevice 但是hDevice并不能直观的对应不同键盘而且每当拔下键盘 重新插入的时候hDevice会发生变化 2 继
  • 每日一库之Go 强大而灵活的电子邮件库:email

    发送邮件是一个很常见的需求 用户邮箱验证 邮箱召回等 Go 语言标准库自带 net smtp 库 实现了 smtp 协议 用于发送邮件 然而这个库比较原始 使用不方便 而且官方声明不再增加新功能 于是乎出现了一些强大的第三方邮件库 今天推荐
  • apifox图片验证码显示

    添加后置脚本 脚本内容如下 var resp response pm response json let img resp response data let template img src img pm visualizer set t
  • USB PHY

    USB PHY负责最底层的信号转换 作用类似于网口的PHY 有两种接口 一种是ULPI 一种是UTMI 前者PIN少 后者PIN多 所以如果用ULPI PHY一般外部另接 用UTMI PIN多 一般内置 PHY内置或者外置要看芯片资料 PO
  • C++ 抽象类

    抽象类 接口 接口描述了类的行为和功能 而无需完成类的特定实现 C 接口时通过抽象类实现的 设计抽象类的目的 是为了给其他类提供一个可以继承的适当的基类 抽象类本类不能被用于实例化对象 只能作为接口使用 注意 如果试图实例化一个抽象类的对象
  • 对接第三文件下载接口,通过restTemplate或java执行linux的cmd指令完成

    文章目录 对接第三文件下载接口 通过restTemplate或java执行linux的cmd指令完成 1 业务场景 2 通过restTemplate exhcange 方法下载文件 3 通过java调用linux指令进行文件下载 4 Web
  • 接口测试教程(一看就会)

    前言 掌握了http协议 就掌握了接口测试 笔者在网络上看过不少接口测试教程 一上来就开始讲怎么操作工具 而不告诉读者为什么要这么操作 读者可能照猫画虎成功了 也可能操作失败了但不知为何出错 因此 本文作为接口测试的入门第一课首先会给大家了
  • 报错为method does not override method from its superclass解决

    你要重写接口的方法就得让实现类实现接口 public class UserServiceImpl implements UserService 没有实现接口就加重写注解 Override 系统不知道重写了什么接口方法 肯定报错 建议巩固一下
  • 接口并发性能测试开发之:从测试方案设计、测试策略、指标分析到代码编写,这一篇全搞定。

    并发接口性能设计思路与代码编写 1 引言 2 并发测试定义 3 并发测试分类 4 设计思路整理 5 测试方案设计 6 指标分析 7 代码实战 8 总结 1 引言 这篇是我3月份在公司内部做的技术分享内容 由于我在公司内部分享的内容较多 以及
  • 容器与云的碰撞——一次对MinIO的测试

    事先声明 本次测试过程完全处于本地或授权环境 仅供学习与参考 不存在未授权测试过程 本文提到的漏洞 MinIO未授权SSRF漏洞 CVE 2021 21287 已经修复 也请读者勿使用该漏洞进行未授权测试 否则作者不承担任何责任 随着工作和
  • 所有OLE接口

    比较有用 记录下来供查阅 常规 函数 lUnknown 目的 控制的接口协商的对象生存期 普遍存在的任何组件 而不考虑实现 QueryInterface 公开传入的接口 函数 IEnum 目的 枚举的各种类型的列表 在许多情况下 整个 OL

随机推荐

  • 【蓝桥杯Python组】寻找2020

    寻找2020 题目描述 小蓝有一个数字矩阵 里面只包含数字 0 和 2 小蓝很喜欢 2020 他想找到这个数字矩阵中有多少个 2020 小蓝只关注三种构成 2020 的方式 同一行里面连续四个字符从左到右构成 2020 同一列里面连续四个字
  • matlab中 hold on 与 hold off,figure作用

    hold on是当前轴及图像保持而不被刷新 准备接受此后将绘制的图形 多图共存 即启动图形保持功能 当前坐标轴和图形都将保持 从此绘制的图形都将添加在这个图形的基础上 并自动调整坐标轴的范围 hold off使当前轴及图像不再具备被刷新的性
  • moviepy音视频剪辑:视频剪辑基类VideoClip详解

    前往老猿Python博文目录 一 概述 在 moviepy音视频剪辑 moviepy中的剪辑基类Clip详解 和 moviepy音视频剪辑 moviepy中的剪辑基类Clip的属性和方法详解 介绍了剪辑相关类及类关系 可以看到视频剪辑类Vi
  • 汽车电子行业静态分析和代码审查规则

    汽车电子行业静态分析和代码审查规则 查了很多编码规则大都是PDF版 最终我整理出了几份word版的 并且帮大家排版好了可直接用于书写测试大纲或报告 下载链接在我的下载中 规则包含以下 1 MISRA C 2012 2 MISRA C 200
  • Node.js入门 03:模块化规范 CommonJS 与 ES Module

    文章目录 目的 CommonJS 基础使用 module 对象 require 方法 ES Module 混合使用 总结 目的 传统的用在网页中的JavaScript代码文件与文件之中的内容都是全局相互可见的 这对于大型项目特别是多人合作的
  • 领域驱动设计:DDD分层架构

    文章目录 DDD 分层架构 DDD 分层架构最重要的原则 DDD 分层架构推动架构演进 三层架构如何演进到 DDD 分层架构 微服务架构模型有好多种 例如整洁架构 CQRS 和六边形架构等等 每种架构模式虽然提出的时代和背景不同 但其核心理
  • 近一月翻阅资料小结

    近一个月接触的东西比较多 梳理一下 Nginx Tomcat 实现负载均衡 同时采用keepalived的形式实现HA 负载后 关键问题就是session共享的问题 可实现的思路较多 Tomcat6以后本身可以使用cluster技术达成 也
  • 训练自己的ai模型(三)学习笔记与项目实操(一些概念理解杂谈)

    ai模型大火 作为普通人 我也想做个自己的ai模型 训练自己的ai模型通常需要接下来的的六步 一 收集和准备数据集 需要收集和准备一个数据集 其中包含想要训练模型的数据 这可能需要一些数据清理和预处理 以确保数据集的质量和一致性 二 选择和
  • PTA——7-3 两个数的简单计算器

    输入格式 输入整数A 符号ch和整数B 输出格式 根据符号ch 在一行中输出A ch B的值 如果ch是 则输出A B的值 如果ch是 则输出A B的值 如果ch是 则输出A B的值 如果ch是 则输出A B的值 题目保证B不为0 并且结果
  • C++泛型编程:源起、实现与意义

    C 泛型编程 源起 实现与意义 为什么泛型泛型编程 Generic Programming 最初提出时的动机很简单直接 发明一种语言机制 能够帮助实现一个通用的标准容器库 所谓通用的标准容器库 就是要能够做到 比如用一个List类存放所有可
  • [Linux]日志文件已删掉磁盘空间不释放,不重启服务进程的解决方法

    Linux 日志文件已删掉磁盘空间不释放 不重启服务进程的解决方法 问题背景 服务进程启动后 后台会有写日志的操作 当服务进程还没停掉 日志就会一直在写 这时候手动删除日志 会造成日志在linux该目录下已经删除 但是磁盘空间不会被释放掉
  • C语言函数操作大全----(超详细)

    fopen 打开文件 相关函数 open fclose 表头文件 include
  • MAC电脑常用效率工具推荐

    作者主页 IT技术分享社区 作者简介 大家好 我是IT技术分享社区的博主 从事C Java开发九年 对数据库 C Java 前端 运维 电脑技巧等经验丰富 个人荣誉 数据库领域优质创作者 华为云享专家 阿里云专家博主 个人博客 IT技术分享
  • supervisor系列:3、配置文件

    supervisor系列 3 配置文件 文章目录 supervisor系列 3 配置文件 1 文件格式 1 1 环境变量 2 unix http server 段设置 2 1 unix http server 段的值 2 2 unix ht
  • VS中Qt中ui文件和生成.h文件问题

    vs中的ui的ui xxxx h头文件是由Qt通过编译生成 vs项目属性中配置环境调用Qt安装目录下bin目录下的uic exe来自动生成代码 如果移动工程目录 而之前又把相关的ui xxx h头文件添加到工程或移动其位置 那么再次修改ui
  • sketchup 255个su常用插件)_「教程」巧用Rhino和SU,做出你想要的地形效果

    Xiao素材 地形建模教程 本期精选 教你如何做好地形效果图 1 SU部分 地形效果 SU插件安装小教程 su软件是我们现在经常会使用到的一个软件 但是在我们作图的过程中会发现 很多情况下 相对于一些复杂的图形我们需要依赖相关的插件 比如
  • python递归函数代码_Python递归函数 二分查找算法实现解析

    一 初始递归 递归函数 在一个函数里在调用这个函数本身 递归的最大深度 998 正如你们刚刚看到的 递归函数如果不受到外力的阻止会一直执行下去 但是我们之前已经说过关于函数调用的问题 每一次函数调用都会产生一个属于它自己的名称空间 如果一直
  • Kubernetes + Dashboard 集群搭建

    1 环境说明 基于kubeadm工具部署k8s 集群 还有基于二进制的部署方式但是需要单独部署k8s的每个组件比较繁琐 kubeadm是 Kubernetes官 提供的 于快速部署Kubernetes集群的 具 基于Kubernetes v
  • OC中的分类与类扩展

    在OC中 对于已有的类进行扩展 我们有两种方式 1 在原始类的定义中 进行代码扩展 2 通过继承的方式 扩展子类 3 使用分类的方式 第一 二种方式不用多说 第三种方式则是OC中比较有特色的功能 分类允许我们在不更改类的原始代码的情况下 实
  • 接口设计之幂等性设计

    幂等性设计 今天我们来聊聊接口的幂等性设计 所谓幂等 就是任意多次执行所产生的影响均与一次执行的影响相同 幂等性接口是指可以使用相同参数重复执行 并能获得相同结果的接口 这里就不展开数学中的定义了 有兴趣的可以自行google 为什么接口需