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

【从零开始学习重要知识点 | 第一篇】快速了解什么是幂等性以及常见解决方案

前言:

        当我们在设计和实现分布式系统时,幂等性是一个非常重要的概念。幂等性可以简单地理解为:对于同一操作,不论执行多少次,产生的影响都是相同的。这个概念在分布式系统中非常重要,因为在这种环境下,由于网络延迟、消息重复等原因,可能会导致同一操作被执行多次。如果操作不具备幂等性,那么这些重复的操作可能会导致系统状态的不一致性、数据的错误或者其他问题。

因此,幂等性是分布式系统中必须要考虑的一个重要问题。在本文中,我们将深入探讨什么是幂等性,为什么它在分布式系统中如此重要,以及如何在设计和实现分布式系统时考虑幂等性。

目录

前言:

什么是幂等性?

常见产生幂等性问题的场景:

常见的幂等解决方案:

1.token机制:

 2.分布式锁:

3.MySQL去重表:

总结:


什么是幂等性?

幂等性简单来讲:对于同一操作,不论执行多少次,产生的影响都是相同的。

换一种方式也可以描述为:

               对于相同的输入,无论进行多少次重复操作,都应该保持其结果一致。

我们来举一个现实的例子:

当我们在用户网站进行注册的时候,当我们因为系统卡顿而多次点击注册按钮的时候,后端肯定不会在数据库生成多个一样的账号密码,而是只有一个账号密码

在这个场景中去解释幂等性:幂等性就是多次重复调用操作(因为卡顿多次点击注册),对结果只影响一次(最终只注册一个账号密码

比方说:支付接口没有做幂等性导致重复扣款问题订单接口没有做幂等性导致的订单重复生成问题

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

因此从后端来看:幂等性就是保证同一个接口在重复接收同一个请求的时候,需要保证效果的唯一性。

常见产生幂等性问题的场景:

  • 网络波动引起的重复请求
  • 使用了失效或者超时重试机制导致接口被重复调用
  • 消息队列中间件的默认重试机制
  • 页面重复刷新
  • 用户重复点击提交按钮
  • 使用浏览器后退按钮重复之前的操作,导致重复提交数据。

前端重复提交消息重复消费任务重复执行

常见的幂等解决方案:

1.token机制:

当用户发起请求之前,后端会生成一个键值对存储在redis中,键是当前请求用户的ip+参数,值是token。

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

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

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

 我们通过携带token的方式,就保证了这种接口的幂等性。

token机制的缺陷:

  1. 复杂性和管理成本 引入 Token 机制会增加系统的复杂性,包括生成、传输、校验和存储 Token 等环节,导致系统开发和维护的成本增加。

  2. 网络开销 每次请求都需要携带 Token,并且服务端需要验证 Token 的有效性,这会增加网络开销和服务端的处理负担,降低系统的性能表现。

  3. 并发冲突 在高并发场景下,可能会出现多个请求同时携带相同的 Token 并被同时处理的情况,导致操作重复执行或者数据不一致的问题。

  4. 安全性风险 如果 Token 不够随机或唯一,可能会受到恶意攻击者的攻击,从而破坏系统的幂等性。此外,泄露 Token 也可能导致安全隐患。

  5. 存储压力 如果大量 Token 需要被管理和存储,可能会给系统的存储带来一定的压力,尤其是在高并发场景下。

 2.分布式锁:

其实就是基于redis去构造一个分布式锁。具体的构造方法的话,这里就不多介绍了,下面是我之前一篇文章的链接,详细的介绍了如何基于redis构造分布式锁。

【从零开始学习Redis | 第六篇】爆改Setnx实现分布式锁-CSDN博客icon-default.png?t=N7T8https://liyuanxin.blog.csdn.net/article/details/134677169那么通过分布式锁来保证幂等性的逻辑也很简单:

我们把传入的参数用户id作为键值对来构造出一个键值对。每一次进来都要尝试构造键值对,如果构造成功,就执行业务逻辑代码,如果没有执行成功,就拒绝这次请求 

第一次构造成功:

 第二次构造失败:

其实就算使用redis中普通的set也是可以的,因为这个本质就是在利用redis中set创建k-v的唯一性

之所以要用setnx,是要保证redis中不会因为构造分布式锁而留下大量的键值对,使用setnx在限定时间后,键值对就会过期被删除。

需要注意的是:我们这种简单的基于setnx构造的锁,会出现锁误删的问题,在我上面贴出来的文章中也详细介绍了锁误删的情况,大家如果想尝试用Redis来构造分布式锁的话,可以看一看。 

这里提到了锁,很多朋友也会关联的想到synchronized,但是synchronized做的是代码块的同步,他会锁住代码块,导致程序并发性能的大大降低。关于这些点我在我上面贴的那篇文章里面也有讲。在这里再贴一下:

【从零开始学习Redis | 第六篇】爆改Setnx实现分布式锁-CSDN博客icon-default.png?t=N7T8https://liyuanxin.blog.csdn.net/article/details/134677169

3.MySQL去重表:

就是在存入MySQL之前,先要检查一下是否有相同数据,如果有相同数据就拒绝插入。

 

总结:

        总之,幂等性在分布式系统和接口设计中扮演着至关重要的角色。通过确保相同操作的重复执行不会产生额外的影响,幂等性能够提升系统的可靠性、稳定性和安全性。然而,实现幂等性并非易事,面临诸多挑战,包括并发冲突、性能开销、安全风险等问题。针对这些挑战,我们可以采取一系列策略和技术手段,例如使用 Token 机制、请求参数校验、消息队列处理等,来确保接口的幂等性。在实际应用中,需要综合考虑系统需求、性能表现和安全要求,选择合适的幂等性解决方案。最终,通过有效地实现幂等性,我们能够构建更加稳健、可靠的系统,为用户提供更好的体验和保障数据的一致性。

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!

 

相关文章:

  • Leetcoder Day29| 贪心算法part03
  • 【0267】pg内核初始化 process table(ProcGlobal、PROC_HDR、PGPROC)分析
  • C语言从入门到实战——预处理详解
  • axios封装
  • ChatGPT 正测试Android屏幕小组件;联想ThinkBook 推出透明笔记本电脑
  • Jmeter基础
  • SpringMVC的文件上传与下载
  • element el-table表格内容宽度自适应,不换行,不隐藏
  • NR 2-STEP RA Absolute Timing Advance Command MAC CE的应用场景
  • 连接未来:嵌入式系统在物联网时代的应用
  • 【每日前端面经】2023-02-27
  • go - 学习笔记 -2
  • 服务器防火墙的应用技术有哪些
  • Redis 16种妙用
  • 黑马程序员——接口测试——day03——Postman断言、关联、参数化
  • 深入了解以太坊
  • 《深入 React 技术栈》
  • 30秒的PHP代码片段(1)数组 - Array
  • IDEA常用插件整理
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • mysql外键的使用
  • 阿里云应用高可用服务公测发布
  • 编写符合Python风格的对象
  • 移动端 h5开发相关内容总结(三)
  • 关于Android全面屏虚拟导航栏的适配总结
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • # 计算机视觉入门
  • #Linux(权限管理)
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (12)Hive调优——count distinct去重优化
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (层次遍历)104. 二叉树的最大深度
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (力扣题库)跳跃游戏II(c++)
  • (转)fock函数详解
  • .apk文件,IIS不支持下载解决
  • .NET Core Web APi类库如何内嵌运行?
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .NET高级面试指南专题十一【 设计模式介绍,为什么要用设计模式】
  • .NET中统一的存储过程调用方法(收藏)
  • .one4-V-XXXXXXXX勒索病毒数据怎么处理|数据解密恢复
  • /deep/和 >>>以及 ::v-deep 三者的区别
  • @data注解_SpringBoot 使用WebSocket打造在线聊天室(基于注解)
  • @RequestMapping 的作用是什么?
  • [《百万宝贝》观后]To be or not to be?
  • [Android]Android开发入门之HelloWorld
  • [BUUCTF]-PWN:wustctf2020_number_game解析(补码,整数漏洞)
  • [BZOJ5125]小Q的书架(决策单调性+分治DP+树状数组)
  • [Docker]六.Docker自动部署nodejs以及golang项目
  • [HackMyVM]靶场 Quick3
  • [IE编程] IE8 新增的C++开发接口
  • [linux] git lfs install 安装lfs