- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
java课程设计⽇历记事本代码,已开源
1.为什么要使⽤分布式锁
使⽤分布式锁的⽬的,⽆外乎就是保证同⼀时间只有⼀个客户端可以对共享资源进⾏操作。
1.1举⼀个很长的例⼦
系统 A 是⼀个电商系统,⽬前是⼀台机器部署,系统中有⼀个⽤户下订单的接⼝,但是⽤户下订单之前⼀定要去检查⼀下库存,确保库存
⾜够了才会给⽤户下单。由于系统有⼀定的并发,所以会预先将商品的库存保存在 Redis 中,⽤户下单的时候会更新 Redis 的库存。此时
系统架构如下:
但是这样⼀来会产⽣⼀个问题:假如某个时刻,Redis ⾥⾯的某个商品库存为 1。
此时两个请求同时到来,其中⼀个请求执⾏到上图的第 3 步,更新数据库的库存为 0,但是第 4 步还没有执⾏。
⽽另外⼀个请求执⾏到了第 2 步,发现库存还是 1,就继续执⾏第 3 步。这样的结果,是导致卖出了 2 个商品,然⽽其实库存只有 1 个。
很明显不对啊!这就是典型的库存超卖问题。此时,我们很容易想到解决⽅案:⽤锁把 2、3、4 步锁住,让他们执⾏完之后,另⼀个线程
才能进来执⾏第 2 步。
按照上⾯的图,在执⾏第 2 步时,使⽤ Java 提供的 Synchronized 或者 ReentrantLock 来锁住,然后在第 4 步执⾏完之后才释放锁。
这样⼀来,2、3、4 这 3 个步骤就被“锁”住了,多个线程之间只能串⾏化执⾏。
当整个系统的并发飙升,⼀台机器扛不住了。现在要增加⼀台机器,如下图:
增加机器之后,系统变成上图所⽰,假设此时两个⽤户的请求同时到来,但是落在了不同的机器上,那么这两个请求是可以同时执⾏了,还
是会出现库存超卖的问题。
因为上图中的两个 A 系统,运⾏在两个不同的 JVM ⾥⾯,他们加的锁只对属于⾃⼰ JVM ⾥⾯的线程有效,对于其他 JVM 的线程是⽆效
的。
因此,这⾥的问题是:Java 提供的原⽣锁机制在多机部署场景下失效了,这是因为两台机器加的锁不是同⼀个锁(两个锁在不同的 JVM
⾥⾯)。
那么,我们只要保证两台机器加的锁是同⼀个锁,问题不就解决了吗?此时,就该分布式锁隆重登场了。
分布式锁的思路是:在整个系统提供⼀个全局、唯⼀的获取锁的“东西”,然后每个系统在需要加锁时,都去问这个“东西”拿到⼀把锁,
这样不同的系统拿到的就可以认为是同⼀把锁。
⾄于这个“东西”,可以是 Redis、Zookeeper,也可以是数据库。此时的架构如图:
通过上⾯的分析,我们知道了库存超卖场景在分布式部署系统的情况下使⽤ Java 原⽣的锁机制⽆法保证线程安全,所以我们需要⽤到分布
式锁的⽅案。
2.⾼效的分布式锁
在设计分布式锁的时候,应该考虑分布式锁⾄少要满⾜的⼀些条件,同时考虑如何⾼效的设计分布式锁,以下⼏点是必须要考虑的:
(1) 互斥
在分布式⾼并发的条件下,最需要保证在同⼀时刻只能有⼀个线程获得锁,这是最基本的⼀点。
(2) 防⽌死锁
在分布式⾼并发的条件下,⽐如有个线程获得锁的同时,还没有来得及去释放锁,就因为系统故障或者其它原因使它⽆法执⾏释放锁的命令,
导致其它线程都⽆法获得锁,造成死锁。所以分布式⾮常有必要设置锁的有效时间,确保系统出现故障后,在⼀定时间内能够主动去释放
锁,避免造成死锁的情况。
(3) 性能
对于访问量⼤的共享资源,需要考虑减少锁等待的时间,避免导致⼤量线程阻塞。
所以在锁的设计时,需要考虑两点。
1、 锁的颗粒度要尽量⼩。⽐如你要通过锁来减库存,那这个锁的名称你可以设置成是商品的ID,⽽不是任取名称。这样这个锁只对当前商品
有效,锁的颗粒度⼩。
2、 锁的范围尽量要⼩。⽐如只要锁2⾏代码就可以解决问题的,那就不要去锁10⾏代码了。
(4) 重⼊
我们知道ReentrantLock是可重⼊锁,那它的特点就是:同⼀个线程可以重复拿到同⼀个资源的锁。重⼊锁⾮常有利于资源的⾼效利⽤。关
于这点之后会做演⽰。
3.基于 Redis实现分布式锁
3.1使⽤ Redis命令实现分布式锁
3.1.1加锁
加锁实际上就是在redis中,给Key键设置⼀个值,为避免死锁,并给定⼀个过期时间。
使⽤的命令**:SET lock_key random_value NX PX 5000**
值得注意的是:
random_value 是客户端⽣成的唯⼀的字符串。
NX 代表只在键不存在时,才对键进⾏设置操作。
PX 5000 设置键的过期时间为5000毫秒。
也可以使⽤另外⼀条命令:SETNX key value
只不过过期时间⽆法设置。
这样,如果上⾯的命令执⾏成功,则证明客户端获取到了锁。
3.1.2解锁
您可能关注的文档
最近下载
- 检验科职业安全防护和职业暴露紧急处理.ppt VIP
- 有机肥料检测报告.docx VIP
- 专题19.5 一次函数的应用【八大题型】(举一反三)(人教版)(解析版).pdf VIP
- (高清版)DG∕TJ 08-2075-2022 管线定向钻进技术标准.docx VIP
- 12J12 河北省12系列建筑标准设计图集 无障碍设施.docx VIP
- 两管理两综合一保护竞赛考试题库-外汇资本项目 .pdf VIP
- 八年级上册数学:专题24 二次根式【八大题型】(举一反三)(北师大版)(解析版).pdf VIP
- 2025年中国四氯化锆项目投资计划书.docx
- 液化石油气钢瓶智能制造项目可行性研究报告模板-备案拿地.doc
- 山西省建筑标准设计图集12J12 12系列建筑标准设计图集 无障碍设施.pdf VIP
文档评论(0)