当前位置: 首页 > news >正文

【思想比实现更重要】高并发场景下如何保证接口幂等性

【AI时代,格局要打开】

朋友,面试经常会被问到’如何保证接口幂等性’吧。你会怎么回答?很多朋友都只磕磕绊绊的回答类似于’加唯一索引’这样几个简单的方案就完了!"

但是你要注意,面试的一大忌讳就是让面试官官觉得你是个’题库型选手’。我一直跟大家强调,面试不是考试,不是题答上了,就好了。而是要真正展现出你的技术经验,思考深度,从单体到分布式,从简单到复杂,层层递进的系统化思考能力
在这里插入图片描述

这一次,我就从这个接口幂等性问题,再次给你分享下如何从应对面试提升到真正构建高可用系统

  • 第一,8种常见的幂等性解决方案,从单体到分布式,一次性全面掌握。
  • 第二,一个从点、线、面出发的系统化思考模型,让你在任何技术挑战面前都能游刃有余。

现在这个大环境,机会越来越难得。这条视频的价值,远不止一个面试题,建议立刻点赞收藏,反复领悟!

【幂等性问题介绍】
在这里插入图片描述

准备任何一个面试题之前,都要思考下为什么。如果不确定一个具体的业务背景,所有的面试题都是夸夸其谈,背再多也没用。这里,我们要先明确一件事:幂等性控制,不是锦上添花,而是必须要做的!

当然,并不是说每个接口,不管什么业务,都一定需要做一些统一的处理,而是这是高手与新手的思维分水岭。为什么你会觉得高手写代码就是靠谱?这种多层面分析问题的习惯,就是答案。哪怕同样用AI,高手也能把AI用得更稳定,更靠谱。

想象一下,用户支付,因为网络抖动,按钮多点了一下,结果扣了两次钱。或者创建一个订单,重复提交,库存扣了两次,生成了两个一模一样的订单。这种事故,对用户是伤害,对公司是灾难。所以,幂等性是任何一个可靠系统的生命线。"

【技术内容讲解】

接下来,上菜!8个常见大招,从青铜到王者,走起!

第一招:查询+插入
在这里插入图片描述

这是最朴素的想法:先SELECT查一下,如果数据不存在,我再INSERT。但这是个典型的错误示范。在高并发下,两个请求就像百米赛跑,可能同时冲过SELECT检查点,都发现’没数据’,然后前后脚INSERT,最终导致数据重复。所以,这招基本不用。"

这一招的优势基本没有。逻辑简单,但只是小白的想法

局限性却很明显,存在致命的并发安全问题,不可靠。当然你也可以把查询和插入操作做成一个事务,但性能就没法要了。

针对这个局限性,就可以有下一招。

第二招:悲观锁
在这里插入图片描述

在查询时就上锁,SELECT 查询时加上 FOR UPDATE。这相当于在处理这条数据时,挂上’请勿打扰’的牌子,其他所有想操作这条数据的请求都得在门外排队。直到我处理完,释放锁,下一个人才能进来。"

这一招的优势:操作简单,能绝对保证数据安全。

但局限性就是性能极差。它把高效的并行处理强行变成了低效的串行排队,在高并发场景下会造成大量请求阻塞,是典型的用性能换安全的做法。

怎么提升性能呢?下一招乐观锁就是一个比较常见的思路。

第三招:乐观锁
在这里插入图片描述

相比悲观锁,这招就聪明多了。我们给核心表加一个version字段。当要更新数据时,SQL这么写。Update的时候增加判断version,同时更新version。这样只有携带正确version的请求才能更新成功,并且成功后立刻让version加1。其他迟到的、携带旧version的请求,都会因为WHERE条件不满足而更新失败。"

这种乐观锁的方式,不产生实际的锁竞争,性能非常高,是一种常用的非常优雅的无锁并发控制。

但他也有局限:需要额外修改表结构,并且它主要防止更新操作的重复,对于防止插入操作的重复无能为力。

如何进一步保护插入操作呢?这就有了下一招。

第四招:唯一索引
在这里插入图片描述

这是数据库层面的金钟罩。给订单号、流水号这种天然唯一的字段加上唯一索引。当重复的请求想INSERT同样的数据时,数据库会第一个站出来拒绝,直接抛出异常。你的代码只需要捕获这个异常,然后就可以轻松的抛弃掉这些重复的请求。

这一招相比乐观锁,就更高效也更可靠了。由数据库层面保证,无需业务代码过多干预。

但他的局限也比较明显:需要业务上有明确的唯一标识。并且在多表关联或者分库分表等一些复杂场景下,全局唯一索引的实现会变得复杂。

怎么解决,这就可以用下面这一招。

第五招:防重表
在这里插入图片描述

当业务表本身不适合加唯一索引时,我们可以建一张独立的’防重表’,把它当成一个’登记处’。这张表结构很简单,只有一个字段,就是你要防重的那个唯一ID,并给它加上唯一索引。每次处理业务前,先INSERT一条记录到防重表里。如果插入成功,就继续处理业务;如果因为唯一索引冲突而失败,就说明是重复请求,直接返回成功。"

通过这种方式就可以将防重逻辑与业务逻辑解耦,不侵入主业务表,非常灵活。

但这一招也同样有局限,那就是多了一次数据库操作,会带来一些性能开销,并且需要和主业务操作放在同一个事务里保证原子性。

怎么办?对于某些特定的业务,可以用下一招状态机来解决。

第六招:状态机
在这里插入图片描述

很多业务流程本身就是一条单行道,比如订单状态只能从’待支付’变成’已支付’,不能反过来。我们可以利用这个特点,在Update时,把状态作为严格的判断条件。只有当订单是’待支付’状态时,更新才会成功。如果订单已经是’已支付’状态,WHERE条件不成立,更新0行,操作自然就幂等地完成了。"

这种方式的好处是:实现非常优雅,与业务逻辑结合紧密,代码可读性好。

但是局限性就是适用场景有限,仅适用于那些具有明确、单向状态流转的业务。

如果业务场景不合适,怎么办?分布式锁就是一个比较通用的方案。

第七招:分布式锁
在这里插入图片描述

进入微服务时代,服务都部署成集群了,内存锁和数据库锁就有点力不从心了。这时需要一个所有服务都能访问的’中央锁’,Redis的SETNX命令就是最佳人选。例如,SET lock:order:xxx 'processing' NX EX 60,这个命令是原子的,NX保证了只有第一个请求能成功设置这个锁,EX 60是给锁加个保质期,防止服务挂了导致死锁。"

这也是分布式环境下的标准解法,通用性强,是解决跨服务、跨节点幂等问题的利器。

但使用分布式锁通常要引入了外部依赖(如Redis),增加了系统复杂度和潜在的故障点。锁的选型和过期时间设计需要仔细考量。当然,在具体实现时,这个简单的Redis指令还是有很多问题。

关于更高效的分布式锁要如何设计,你可以在评论区说下你的想法,在看视频的同时,做个技术回顾。

既然分布式锁太复杂,有没有比较简单一点的方案呢?接下来

第八招:Token令牌
在这里插入图片描述

这是前后端协作的经典方案,像发一张’一次性门票’。前端在进入操作页面时,先调接口领一个唯一令牌。提交操作时,把这个令牌一起发给后端。后端收到请求,先判断令牌是否正确,如果正确,就删除这个令牌。如果删除成功,说明是第一次请求,处理业务;如果删除失败,说明令牌已经被用过了,直接拒绝。

这种方案非常灵活,将防重前置,能有效防止用户重复点击、网络重试等多种场景,安全性高。像面试的常客OAuth2.0,其实整体也是采用的这种思路。

当然同样也有局限性。这种方案需要前后端配合改造,一次业务操作需要两次网络请求(获取、使用),增加了交互的复杂性。

【总结与升华】

在这里插入图片描述
所以你看,一个看似简单的接口幂等型问题,从数据库到业务,再到分布式架构,没有哪一招是万能的。而这背后,其实是从单一方案的“点”,串联成整个业务流程的“线”,最终构成了整个系统架构的“面”。

而这种思维模型才是所有面试官想看到的,一个成熟工程师的系统化思考能力。也是我一直强调的AI时代,程序员的核心竞争力。

最后记住:“精通招式,可立于不败;洞悉思维,方能无往不利。

http://www.dtcms.com/a/532097.html

相关文章:

  • Spring Expression Language (SpEL) 详解:功能强大的表达式引擎
  • LeetCode:773. 滑动谜题
  • MATLAB基于类别加权灰靶决策的教学评价研究
  • C16可变参数模板函数和普通函数模板
  • 网站建设规划设计方案建设部门电工证查询网站
  • ​​lseek​​的“时空跳跃”:从获取大小到制造“文件空洞”
  • 技术演进中的开发沉思-151 java-servlet:会话管理
  • 【IO多路转接】IO 多路复用之 select:从接口解析到服务器实战
  • 淄博周村学校网站建设定制wordpress文章和页面
  • Multitouch for mac 触控板多点手势创建
  • SIGCHLD:进程终止与僵尸进程清理的关键
  • 数据结构(10)
  • 南皮做网站的团队管理的七个要点
  • Mysql的数据备份和高可用
  • 【Kotlin】数组集合常用扩展函数
  • css新增盒子属性——尺寸调节
  • 做阿里国际网站会有成效吗上海网站建设公司招人
  • 【课堂笔记】概率论-3
  • 【硬件基础篇】:CPU如何被制造出来
  • 面向模块的综合技术之控制集优化(七)
  • 做网站广告软件网站系统设计目标
  • 使用稀疏采样方法减轻汽车雷达干扰——论文阅读
  • 阮一峰《TypeScript 教程》学习笔记——d.ts 类型声明文件
  • Spring AOP:横切关注点的优雅解决方案
  • 如何申请网站空间和注册域名鞋子软文推广300字
  • 基于AutoDL远端服务器在pycharm复现:具身智能论文pai0
  • 如何看访问网站的dns网站开发难不难
  • 数据结构·堆
  • 阮一峰《TypeScript 教程》学习笔记——类型映射
  • 需要做网站建设和推广网站地图插件