场景:
最近遇到一个account dubbo服务的并发注册问题,日志中抛出了大量的主键冲突问题。注册用户过程中有多个SQL操作,且这些SQL可以实现单机本地事务。
为何单机锁不能解决问题?正如下图请求是发送到不同的节点上的,单机的锁只能控制单节点的并发请求。
解决思路:
如果加锁操作,会极大的减少主键冲突的日志。开始写了一版最直接的思路,后来发现dubbo服务中很多地方都可能出现并发问题,肖老板指导说可以做的更抽象点,如果jar包的形式提供出来,那么别的工程也可以复用这套逻辑了。所以后来又做了一版抽象,模型主要分成幂等锁和非幂等锁。
系统架构图:
cache能实现分布式锁的原因是所有的putIfAbsent这种操作都放在了单机节点的队列上做串行操作,所以也就避免了分布式锁的问题。
流程图:
非幂等的情况很简单,没有抢到锁直接返回就是。幂等的情况比较复杂,从下面的流程图可以看出有轮询的过程。
缺点:
这个也是我看了别人的分布式锁框架对比发现的,跟别人一对比发现还是有挺多东西可以学习借鉴下的。
1. 对代码侵入性大,最好能直接提供注解的方式,不影响业务逻辑代码。对非幂等的接口比较好处理,但是对于幂等的接口则难度较大,毕竟需要有地方承载轮询的代码啊。
2. 实现单一,仅仅实现nkv,其实可以更抽象一层,然后以nkv,redis zk的方式实现。
3. 我理解幂等其实一般都不用分布式锁了,即使并发请求也没啥关系啊,我们这是奇葩情况。
核心代码:
public interface ConcurrencyService { /** 幂等的并发返回的枚举值定义 */ /** 获取到并发锁 */ final int GET_CONCURRENCY_LOCK = 1; /** 轮询事务对象成功 */ final int GET_TRANSACTION_RET_OBJECT = 2; /** 轮询事务对象失败 */ final int NOT_GET_TRANSACTION_RET_OBJECT = 3; /** * 获取分布式并发的锁(非幂等) * @param key * 请求并发锁的标识 * @return */ public boolean getConcurrencyLock(String key) ; /** * 获取分布式并发的锁(幂等) * @param key * 请求并发锁的标识 * @param interval * 轮询的间隔时间(ms),默认是20ms * @param concurrencyLoopCallBack * 用于轮询抢到分布式锁的事务是否成功的回调方法 * @return */ public int getConcurrencyLock(String key,Long interval, IConcurrencyLoopCallBack concurrencyLoopCallBack) ; }
public interface IConcurrencyLoopCallBack { /** * 用于并发幂等的场景,方法主要用于第三步 * 1. 查询对象不存在 * 2. 获取分布式锁 * 3. 获取锁失败则使用这个方法来进行轮询 * 4. 返回true 则说明验证事务操作成功 * 5. 返回false 则说明轮询失败针对具体业务做不同处理 * @return */ boolean getTransactionRetObject(); }
@Service("concurrencyService") public class ConcurrencyServiceImpl extends CacheSupport<Object> implements ConcurrencyService { /** 缓存在多久之后失效(单位s) */ public final Integer overDate = 5; /** 默认的轮询间隔时间 */ public final Long defaultInterval = 20L; /** 轮询次数 */ public final int tryTimes = 3; @Override public boolean getConcurrencyLock(String key) { NkvClient.NkvOption nkvOption = new NkvClient.NkvOption(); nkvOption.setExpireTime(overDate); return setIfNotExist(key, true, nkvOption); } @Override public int getConcurrencyLock(String key, Long interval, IConcurrencyLoopCallBack callBack) { boolean transactionRet = false; try { // 获取并发控制权 boolean getLock = getConcurrencyLock(key); LogConstant.accountLog.info("cacheKey:" + key + " ,getConcurrencyLock result :" + getLock); if(getLock) { return GET_CONCURRENCY_LOCK; } // 设置默认间隔时间 if(null == interval) { interval = defaultInterval; } int tryingTime = 0; while(!transactionRet && tryingTime < tryTimes) { Thread.sleep(interval); tryingTime ++; transactionRet = callBack.getTransactionRetObject(); LogConstant.accountLog.info("cacheKey:" + key + "the " + tryingTime + "th try , transaction is successful ? " + transactionRet); } } catch (Exception e) { LogConstant.accountLog.error("getConcurrencyLock Exception", e); } if(transactionRet) { return GET_TRANSACTION_RET_OBJECT; } return NOT_GET_TRANSACTION_RET_OBJECT; } }
相关推荐
本文提出了一种基于虚拟化的水务分布式大数据存储平台设计方案,以Hadoop基础架构和虚拟化技术为核心,实现了一种新的存储模式。 首先,文章介绍了分布式存储的概念,即数据分散存储到多个数据存储服务器上,采用...
总的来说,RPC-DDSF框架的提出为分布式系统的开发提供了一种新的思路和工具,它能够帮助开发者快速构建可配置、可扩展和高性能的分布式数据共享应用。这种框架的设计和应用对于希望在分布式环境下提高数据处理效率的...
比如,Google的GFS(Google File System)为大规模数据存储提供了支持,HDFS(Hadoop Distributed File System)便是沿用了GFS的设计思路,是一种高容错性的分布式文件系统,它允许数据跨多个物理节点存储,以提高...
总之,本文所述的通用核心框架设计,是一种系统化、模块化的设计思路,强调在系统开发初期就关注顶层设计的标准化和模块化,通过技术手段封装通用模块,最终达到降低耦合、提高效率、增强系统灵活性和可扩展性的目的...
为解决这些问题,本研究提出了一种新的基于业务抽象规划的分布式动态服务组合算法。该算法的核心思路是在服务组合过程中,根据组合规划结果动态扩充业务抽象规划库,从而快速地组合出满足需求的服务,并逐步提高服务...
4. 算法的关键步骤和组成部分:离散型粒子群优化算法在分布式ETL任务调度中的应用主要包括ETL工作调度模型的抽象化、算法编码的设计、目标函数的选择等。通过理论分析和实验验证了该策略的有效性和效率。 5. 理论和...
总的来说,这篇文章深入探讨了大规模分布式系统结构脆弱性的问题,提出了一种创新的分析方法,对于提升分布式系统的安全性具有重要的理论和实践意义。通过多层拓扑模型和映射-回溯算法,该研究为理解和处理分布式...
它不仅为混成系统故障诊断提供了一种新思路,而且还展示了如何利用分布式自动机和混合键合图技术来提高诊断效率和准确性。这种诊断方法有望在未来的混成系统和分布式系统开发中发挥重要的作用。
总结来说,"基于组织的分布式开放系统自适应机制"是一种创新的解决思路,它利用社会学和组织学的理论来解决分布式系统中的自适应问题,通过组织元模型和动态重组机制,提高了系统的适应性和灵活性。这种方法对于构建...
这种设计方法提供了一种成本更低的解决方案,使得中小企业也能享受到分布式数据库带来的优势,而不必投入巨额资金购买昂贵的商业分布式数据库。 文章的关键词包括:分布式数据层、逻辑表、物理表。这些关键词概括了...
分布式体系架构是一种利用网络将物理上独立的计算机或节点连接起来,共同完成一项或多项任务的系统结构。与传统的集中式架构相比,分布式体系具有高可扩展性、高可靠性、容错性强和灵活的网络拓扑结构等特点。分布式...
本文提出了一种基于Kubernetes的分布式计算环境构建方法,包括四个步骤:安装Linux操作系统、安装Kubernetes、选择主节点并初始化、其他节点加入主节点形成计算资源池。这种方法可以快速搭建起分布式计算环境,并能...
分布式文件系统是一种允许通过网络透明地访问存储在多个物理存储设备上的文件的计算机文件系统。它是大型分布式计算环境中不可或缺的部分,其性能直接影响整个计算环境的执行效率。网络分布式文件系统(NDFS)的设计...
分布式流计算是一种处理大规模数据流的技术,它可以处理实时数据,并且具有低延迟和高可靠性的特点。在分布式流计算系统设计中,核心指标包括低延时和高可靠性。这类系统在科技公司的在线和近线海量数据处理中占有...
总结来说,这篇论文提供了一种创新的、基于Agent的自适应能耗管理策略,为分布式嵌入式系统的能源效率提升提供了新的思路,同时也为相关领域的研究和实践提供了重要的参考。通过DE-Net模型和CTL/Petri网工具,开发者...
分层模型是组织和处理情境信息的一种有效结构,它通过抽象化的方法简化了信息处理流程。而感知主动性则反映了情境感知系统响应环境变化的能力和灵活性。 此外,本文所引用的中图分类号TP302.7,文献标识码A,电子...
分布式云架构是云计算的一种模式,它能够提供可扩展的计算资源池,让资源能够更加灵活和高效地分配和利用。在云计算的三种服务模型(SaaS、PaaS、IaaS)中,IaaS(基础设施即服务)提供了底层的硬件资源,如服务器、...
这不仅仅是对现有仿真方法的补充,更是一种全新的研究方法论,能够为分布式系统的未来研究和发展提供新的思路和工具。通过对信任模型的深入分析和仿真,能够在设计阶段预见并解决可能出现的问题,从而降低系统的维护...