高并发核心技术——幂等性 与 分布式锁!!!

探秘幂等性设计——唯一索引,乐观锁,悲观锁,分布式锁 本文深入探讨了幂等性设计在构建高可用、高并发分布式系统中的重要作用。文章首先介绍了幂等性的概念和常见实现方案,如唯一索引、乐观锁和悲观锁。接着重点分析了高并发场景下实现幂等性的难点,并提出引入分布式锁的解决方案,详细介绍了分布式锁的原理、实现和注意事项。 阅读详情

一、高并发核心技术之 - 幂等性

1.  什么是幂等性

幂等性就是指:一个幂等操作任其执行多次所产生的影响均与一次执行的影响相同。 用数学的概念表达是这样的: f(f(x)) = f(x). 就像 nx1 = n 一样, x1 就是一个幂等操作。无论是乘以多少次结果都一样。

2.  常见的幂等性问题

幂等性问题经常会是由网络问题引起的,还有重复操作引起的。

场景一:比如点赞功能,一个用户只能对同一片文章点赞一次,重复点赞提示已经点过赞了。

示例代码:

    public void like(Article article,User user) { 
    //检查是否点过赞     
    if (checkIsLike(article,user)) { 
    //点过赞了     
    throw new ApiException(CodeEnums.SYSTEM_ERR); 
    } else { 
    //保存点赞     
    saveLike(article,user); 
    } 
    }
     </pre>

看上去好像没有什么问题,保存点赞之前已经检查过是否点赞了,理论上同一个人不会对同一篇文章重复点赞。但实际不是这样的。因为网络请求不是排队进来的,而是一窝蜂涌进来的。

某些时候,用户网络不好,可能很短的时间内点击了多次,由于网络传输问题,这些请求可能会同时来到我们的服务器。

  • 第一个请求 checkIsLike() 返回 false , 正在执行 saveLike() 操作,还没来的及提交事务

  • 第二个请求过来了 ,checkIsLike() 返回 也是 false , 并去 执行了 saveLike() 操作

这样子,就造成了一个用户同时对一篇文章进行了多次点赞操作。

这就是典型的幂等性问题, 操作了一次和操作了两次结果不一样,因为你多点了一次赞,按照幂等性原则 不管你点击了多少次结果都一样,只点了一次赞。

很多场景都是这样造成的,比如用户重复下单,重复评论,重复提交表单等。

那怎么解决呢? 假设网络的请求是排队进来的就不会出现这个问题了。

于是我们可以改成这样:

public synchronized void like(Article article,User user) { //检查是否点过赞 if (checkIsLike(article,user)) { //点过赞了 throw new ApiException(CodeEnums.SYSTEM_ERR); } else { //保存点赞 saveLike(article,user); } } </pre> 复制代码

synchronized 同步锁 这样我们的请求就会乖乖的排队进来了。

PS :这样做是效率比较低的做法,不建议这么做,只是举例子,synchronized 也不适合分布式集群场景。

场景二 : 第三方回调

我们系统经常需要和第三方系统打交道,比如微信充值,支付宝充值什么的,微信和支付宝常常会以回调你的接口通知你支付结果。为了保证你能收到回调,往往可能会回调多次。

有时候我们也为了保证数据的准确性会有个定时器去查询支付结果未知的流水,并执行响应的处理。 如果定时器的轮训和回调刚好是在同时进行,这可能又出BUG了,又进行了两次重复操作。

那么问题来了: 假设我是一个充值操作, 回调回来的时候 ,会做业务处理,成功了给用户账户加钱。这是后就要保证幂等性了, 假设微信同一笔交易给你回调了两次,如果你给用户充值了两次,这显然不合理(我是老板肯定扣你工资),所以要保证 不管微信回调你多少次 ,同一笔交易你只能给用户充一次钱。这就幂等性。

二、解决幂等性问题方案

  • synchronized 适合单机应用,不追求性能 ,不追求并发。

  • 分布式锁 但是往往我们的应用是分布式的集群,并且很讲究性能,并发,所以我们需要用到 分布式锁 来解决这个问题。

Redis 分布式锁:

/** * setNx * *  
@param key *  
@param value *  
@return 
*/ 
public Boolean setNx(String key,Object value) { 
return redisTemplate.opsForValue().setIfAbsent(key,value); 
} 
/**
 *  @param key 锁
  *  @param waitTime 等待时间  毫秒 
  *  @param expireTime 超时时间  毫秒 
  *  @return */ 
  public Boolean lock(String key,Long waitTime,Long expireTime) { 
  String vlaue =  UUIDUtil.mongoObjectId(); 
  Boolean flag = setNx(key,vlaue); 
  //尝试获取锁  成功返回 
  if (flag) { 
  redisTemplate.expire(key,expireTime,TimeUnit.MILLISECONDS); 
  return flag; 
  } else { 
  //失败 
  //现在时间 
  long newTime =  System.currentTimeMillis(); 
  //等待过期时间 
  long loseTime = newTime + waitTime; 
  //不断尝试获取锁成功返回 
  while (System.currentTimeMillis()  < loseTime) 
  { 
  Boolean testFlag = setNx(key,vlaue); 
  if (testFlag) { 
  redisTemplate.expire(key,expireTime,TimeUnit.MILLISECONDS); 
  return testFlag; 
  } 
  //休眠100毫秒 
  try { 
  Thread.sleep(100); 
  } catch (InterruptedException e) { 
  e.printStackTrace(); 
  } 
  }
  }
  return false;
  }
  /** 
  *  @param key 
  *  @return 
  */ 
  public Boolean lock(String key) { 
  return lock(key,1000L,60  *  1000L); 
  } 
  /** *  
  @param key 
  */ 
  public void unLock(String key) { 
  remove(key); 
  } 
  </pre>

利用Redis 分布式锁 我们的代码可以改成这样:

public void like(Article article,User user) { 
String key =  "key:like"  + article.getId()  +  ":"  + user.getUserId(); 
//  等待锁的时间  0  ,  过期时间  一分钟防止死锁 
boolean flag = redisService.lock(key,0,60  *  1000L); 
if(!flag) { 
//获取锁失败  说明前面的请求已经获取了锁 
throw new ApiException(CodeEnums.SYSTEM_ERR); 
} 
//检查是否点过赞 
if (checkIsLike(article,user)) { 
//点过赞了 
throw new ApiException(CodeEnums.SYSTEM_ERR); 
} else { 
//保存点赞 
saveLike(article,user); 
} 
//删除锁 
redisService.unLock(key); 
} 
</pre>

key 的设计也很讲究: 数据不冲突的两个业务场景,key不能冲突,不同人的key也不一样,不同的文章Key也不一样。 根据场景业务设定。

一个原则: 尽可能的缩小key的范围。 这样才能增强我们的并发。

首先我们先获取锁,获取锁成功 执行完操作,保存数据 ,删除锁。获取不到锁返回失败。设置过期时间是为了防止‘死锁’,比如机器获取到了 锁,没有设置过期时间,但是他死机了,没有删除释放锁。

  • 版本号控制 CAS 算法: CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。这个比较繁杂,有兴趣的同学可以去看看。

 

Redis分布式锁解决接口幂等的两种方案 Redis分布式锁解决接口幂等的两种方案一、背景二、基础知识三、解决方案四、实验五、说在最后的话 一、背景 还在为不了解分布式锁而烦恼吗?还在为众多微服务接口不幂等而发愁吗?如果是,并且有兴趣同我一起学习,那请接着看本文,通过本文能够学习到分布式锁的基本原理、如何实现分布式锁以及使用分布式锁解决接口幂等问题。 二、基础知识 本文是通过使用 Redis 实现分布式锁,当然也可用使用各大数据库,比如 Mysql、Oracle 自持的行级锁、大厂的 Zookeeper 等方案实现。 分布式锁的基本思想 我们既然称其为“锁”,那就是说只有唯一的一把钥匙才能将锁打开,将这种思想放到我们软件设计上来,那就 立即下载

相关推荐

TCN+iTransformer时间序列预测实战:从风电功率预测到源码解析(附完整代码)

本文深入探讨了TCN与iTransformer融合模型在时间序列预测,特别是风电功率预测中的应用。通过解析iTransformer‘倒置’视角的创新架构与TCN强大的局部时序捕捉能力,文章提供了完整的融合方案设计、源码实现及实战调优经验,旨在构建更强大的下一代预测引擎。

weixin_29062671的博客 266

分布式锁实现业务幂等

1、前言 现如今很多系统都会基于分布式或微服务思想完成对系统的架构设计。那么在这一个系统中,就会存在若干个微服务,而且服务间也会产生相互通信调用。那么既然产生了服务调用,就必然会存在服务调用延迟或失败的问题。当出现这种问题,服务端会进行重试等操作或客户端有可能会进行多次点击提交。如果这样请求多次的话,那最终处理的数据结果就一定要保证统一,如支付场景。此时就需要通过保证业务幂等性方案来完成。 *2*|***0***什么是幂等 幂等本身是一个数学概念。即 f(n) = 1^n ,无论n为多少,f(n)的值永远为

奔波儿东 2575

MarkDown简介(深度解析MarkDown用法)

欢迎使用Markdown编辑器写博客 本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: Markdown和扩展Markdown简洁的语法 代码块高亮 图片链接和图片上传 LaTex数学公式 UML序列图和流程图 离线写博客 导入导出Markdown文件 丰富的快捷键 快捷键 加粗 Ctrl + B 斜体 Ctrl + I...

酷酷的旭 7344

高并发核心技术 - 幂等性 与 分布式锁

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34235105的博客 255

2025年度工业级3D全景相机技术解析选型参考:国产品牌的技术突围与市场格局

本文分析了工业级3D相机在智慧城市和建筑数字化中的应用。通过对比国内外主流设备的技术参数和应用场景,发现国产品牌如众趣科技在性价比和本地化服务方面具有优势,尤其适合大型空间扫描项目;而国际品牌如Faro、Leica则在精度和可靠性上保持领先。建议根据项目需求(如测距范围、精度要求、预算)进行设备选型,综合考虑扫描效率、数据处理能力和系统兼容性。国产品牌已在国内大型基建项目中展现出竞争力,国际品牌则更适合高精度逆向工程和国际化项目。

gxdtgsy的博客 1077

数字电路逻辑与设计实验三 译码器和数据选择器

1. 译码器功能测试 将 74LS139 按图 3.1 接线,按表 3.2 输入电平分别置位,填输出状态表。 2. 译码器转换 将双 2-4 线译码器转换为 3-8 线译码器。 (1)画出转换电路图。 (2)在实验箱上接线并验证设计是否正确。 (3)设计并填表写该 3-8 线译码器功能表,画出输入、输出波形。 3. 数据选择器的测试及应用 (1) 将双 4 选 1 数据选择器 74LS153 参照图 3.2 接线,测试其功能并填写功能表 3.3。 (2)将实验箱脉冲信号源中固定连续脉冲 4 个不

欢迎交流学习心得 3088

幂等与分布式锁的区别及应用场景

是分布式系统中两个重要的概念,它们解决的问题和应用场景有所不同。例如:多个节点同时竞争一个资源时,使用分布式锁确保只有一个节点可以访问该资源。:为每个请求分配唯一标识(如 UUID),并在服务端记录已处理的请求标识。例如:HTTP 的 GET 请求是幂等的,因为多次请求不会改变资源状态。多个节点竞争执行定时任务时,使用分布式锁确保任务只被一个节点执行。多个节点同时扣减库存时,使用分布式锁确保只有一个节点可以扣减。根据业务需求选择合适的机制,确保系统的正确性和性能。消费者处理消息时,记录消息的唯一标识。

C18298182575的博客 689

SAP Gateway 中事务码 /IWFND/MAINT_SERVICE 的用法介绍

本文系统梳理了SAP Gateway中/IWFND/MAINT_SERVICE事务码的核心功能与运维实践。作为OData服务管理中樞,它支持服务注册激活、ICF节点配置、系统别名绑定、批量处理等关键操作。文章详解了服务目录、ICF节点、系统别名的配置要点,提供了批量激活、缓存清理、性能监控等实用技巧,并针对常见陷阱(如传输配置、删除残留)给出解决方案。通过制造业批量激活、零售业OAuth集成等案例,展示了事务码在企业级应用中的实际价值,为SAP Gateway运维提供了一套完整的治理清单。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 314

高并发核心技术 - 幂等性与分布式锁

高并发核心技术之 - 幂等性 1. 什么是幂等性 幂等性就是指:一个幂等操作任其执行多次所产生的影响均与一次执行的影响相同。用数学的概念表达是这样的: f(f(x)) = f(x).就像 nx1 = n 一样, x1 就是一个幂等操作。无论是乘以多少次结果都一样。 2. 常见的幂等性问题 幂等性问题经常会是由网络问题引起的,还有重复操作引起的。 场景一:比如点赞功能,一个用户只能对同一片文章点...

171

创建 Fiori Space 时看不到传输请求的根因与排查路径

摘要: 在创建Fiori Space时,若Transport字段下拉列表为空,通常是因为系统未找到符合要求的传输请求。主要原因是: 请求类型不匹配:需使用Customizing request而非Workbench request。 用户权限问题:当前用户需在请求下有可用的task。 客户端或系统不一致:请求需在当前客户端和正确系统(如后端)中创建。 解决方法: 在当前客户端和系统中新建Customizing request,确保包含用户task。 检查是否为前后端分离架构,确保请求创建在正确的系统。 验证

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 107

uniapp:微信支付报错requestPayment:fail errors,uniAPP调用uni.requestPayment微信支付提示错误(安卓app、ios苹果app、微信小程序支付报错)

uniapp微信支付报错requestPayment:fail errors,uniApp APP端调起微信支付失败报错requestPayment:fail errors,uniapp微信小程序支付的坑 “errMsg“: “requestPayment:fail errors“,uni.requestPayment微信支付,UNI-APP支付报错“errMsg“: “requestPayment:fail errors“ app微信支付,uniapp 安卓app微信支付报错,uni.requestPay

✅ 精选推荐文章 3917

TDengine taosX OPC UA 客户端证书生成指南:从 PEM 生成、SAN 校验到 taosExplorer 上传与服务端信任

在 TDengine 的零代码数据接入(taosX / taosExplorer)体系中,当 OPC UA 服务端的 **Security Mode** 配置为 `Sign` 或 `SignAndEncrypt` 时,taosX 必须以"客户端证书 + 私钥"的方式与服务端建立安全通道(Secure Channel)。本指南以 [生成 taosX OPC UA 客户端证书](https://lin

gitblog_00124的博客 1173

Unet++改进33:添加ConvolutionalGLU(2024最新改进方法)|紧凑的网络结构和高效的运算

由于残差连接的深度退化效应,许多依赖堆叠层进行信息交换的高效视觉变形模型往往不能形成足够的信息混合,导致视觉感知不自然。为了解决这个问题,在本文中,我们提出了聚合注意力,这是一种基于仿生设计的令牌混合器,它模拟生物中央凹视觉和连续眼运动,同时使特征映射上的每个令牌具有全局感知。此外,我们结合了可学习的令牌,与传统的查询和键交互,这进一步多样化了亲和矩阵的生成,而不仅仅依赖于查询和键之间的相似性。我们的方法不依赖于堆叠进行信息交换,从而有效地避免了深度退化,实现了自然的视觉感知。

AIcurator的博客 685

高并发下如何保证接口的幂等性

本文介绍了高并发场景下保障接口幂等性的五种技术方案:1)Token机制通过申请校验唯一Token防重;2)数据库唯一索引利用约束防重复插入;3)分布式锁确保同一请求串行处理;4)状态机机制基于业务流转状态实现更新幂等;5)乐观锁通过版本号控制并发更新。文章对比了各方案的适用场景和优缺点,指出Token机制适合前端防重点击,唯一索引最可靠但仅限新增场景,状态机方案最优雅但需业务支持。最后强调实现时需注意先删Token后执行业务、避免先查后改陷阱等关键细节。

欢迎大家指正与批评,还有掘金同名博客欢迎大家关注 809

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

高并发的核心技术中如何实现幂等性问题的研究

链接:https://www.zhihu.com/question/27744795/answer/234251693 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 实际系统中有很多操作,是不管做多少次,都应该产生一样的效果或返回一样的结果。 例如: 1. 前端重复提交选中的数据,应该后台只产生对应这个数据的一个反应结果。 2. 我们发

陈守璐的专栏 4251

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

MXNet 在云平台 CPU 实例上的部署指南:pip、Docker 与 AWS Deep Learning AMI 三种方案

本文以 MXNet 官方安装文档中面向“云平台 CPU 实例”的安装指引为核心,系统讲解在任意云厂商纯 CPU 实例上部署 MXNet 的三种主流方式:Python pip 安装、Docker 容器安装,以及 AWS Deep Learning AMI 预装环境。读完本文,你将掌握各方案的适用场景、具体命令、MKL-DNN 加速包的选型规则,以及如何在云上快速验证 MXNet 是否可用。 ##

gitblog_01111的博客 1114

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

JEECG-Boot接口幂等性架构设计:Token机制与分布式锁完整实现方案

在分布式系统架构设计中,接口幂等性是保障数据一致性和系统稳定性的核心技术挑战。JEECG-Boot作为企业级AI低代码平台,通过创新的Token机制与分布式锁双轨方案,为开发者提供了一套完整的幂等性解决方案。这套方案不仅解决了重复提交和并发冲突问题,更在AI驱动的低代码开发模式下,实现了接口幂等性的智能化配置与管理。 ## 技术挑战:分布式环境下的幂等性困境 在微服务架构和分布式系统中,接口幂

gitblog_01016的博客 878

在高并发的核心技术中如何实现幂等性

在高并发的核心技术中如何实现幂等性  https://blog.youkuaiyun.com/rdhj5566/article/details/50646599 如何保证微服务接口的幂等性       https://blog.youkuaiyun.com/wangyan9110/article/details/70953273     必测的支付漏洞(二)支付流程中“幂等性”   https://blog.csd...

ziyouniao719672119的专栏 2665

java 支付回调 并发_阿里P6谈高并发中的幂等性控制!新手:涨知识了

分享阿里 P8 高级架构师吐血总结的 《Java 核心知识体系&面试资料.pdf》,外加 100G 面试学习视频文档据说是阿里 P8 级高级架构师吐血总结的一份 Java 核心知识.pdf, 内容覆盖很广,Java 核心基础、Java 多线程、高并发、Spring、微服务、Netty 与 RPC、Zookeeper、Kafka、RabbitMQ、Habase、设计模式、负载均衡、分布式缓存...

weixin_28884205的博客 984
上一篇: 这几道Redis面试题都不懂,怎么拿offer?
下一篇: 一篇文章带你深入解析Redis主从复制机制!
加班不秃顶
博客等级 码龄7年 1822粉丝 599原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值