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

news/2025/3/14 8:37:32/

前言:

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

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

目录

前言:

什么是幂等性?

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

常见的幂等解决方案:

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 机制、请求参数校验、消息队列处理等,来确保接口的幂等性。在实际应用中,需要综合考虑系统需求、性能表现和安全要求,选择合适的幂等性解决方案。最终,通过有效地实现幂等性,我们能够构建更加稳健、可靠的系统,为用户提供更好的体验和保障数据的一致性。

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

 


http://www.ppmy.cn/news/1365116.html

相关文章

【机器人最短路径规划问题(栅格地图)】基于蚁群算法求解

基于蚁群算法求解机器人最短路径规划问题的仿真结果 仿真结果 收敛曲线变化趋势 蚁群算法求解最优解的机器人运动路径 各代蚂蚁求解机器人最短路径的运动轨迹

利用Spring Boot实现MQTT在物联网中的应用

在物联网(IoT)领域,消息队列遵循发布/订阅模型的MQTT(Message Queuing Telemetry Transport)协议变得越来越受欢迎。本文将深入探讨如何在Spring Boot中使用MQTT,并讨论其与其他中间件的集成以及在物联网中…

【vue】vue 是怎么把 template 模版编译成 render 函数的,什么是AST抽象语法树

什么是AST 抽象语法树 是一个对象/或者json是一个数据结构 AST通常是由多个节点组成的树状结构,每个节点代表一个语法单位或表达式。节点之间的关系通过父子关系或兄弟关系来表示程序的结构。在不同的编程语言和工具中,AST可能有不同的表示方式和节点类…

【深度学习笔记】深度卷积神经网络——NiN

网络中的网络(NiN) LeNet、AlexNet和VGG都有一个共同的设计模式:通过一系列的卷积层与汇聚层来提取空间结构特征;然后通过全连接层对特征的表征进行处理。 AlexNet和VGG对LeNet的改进主要在于如何扩大和加深这两个模块。 或者&am…

FPGA 与 数字电路的关系 - 这篇文章 将 持续 更新 :)

先说几个逻辑:(强调一下在这篇文章 输入路数 只有 1个或2个,输出只有1个,N个输入M个输出以后再说) 看下面的几个图: 图一( 忘了 这是 啥门,不是门吧 :)也就…

Swagger接口文档管理工具

Swagger 1、Swagger1.1 swagger介绍1.2 项目集成swagger流程1.3 项目集成swagger 2、knife4j2.1 knife4j介绍2.2 项目集成knife4j 1、Swagger 1.1 swagger介绍 官网:https://swagger.io/ Swagger 是一个规范和完整的Web API框架,用于生成、描述、调用和…

Day03:Web架构OSS存储负载均衡CDN加速反向代理WAF防护

目录 WAF CDN OSS 反向代理 负载均衡 思维导图 章节知识点: 应用架构:Web/APP/云应用/三方服务/负载均衡等 安全产品:CDN/WAF/IDS/IPS/蜜罐/防火墙/杀毒等 渗透命令:文件上传下载/端口服务/Shell反弹等 抓包技术&#xff1a…

迭代器模式(Iterator Pattern)

定义 迭代器模式(Iterator Pattern)是一种行为型设计模式,它提供了一种方法来顺序访问聚合对象中的各个元素,而不需要暴露该对象的内部表示。迭代器模式使得客户端代码能够独立于聚合对象的具体实现进行遍历操作。 在迭代器模式…