集成Redis分布式锁-继续项目实战 (集成热地板)

教程大全 2025-07-16 11:48:23 浏览

继续项目实战,集成Redis分布式锁

2021-03-10 09:54:06今天我们就来把基于Redis实现的分布式锁,集成到我们的项目中,分布式锁历来都受到大家的关注。不管是工作中、面试中,分布式锁永远是个不老的话题,也希望大家能掌握此技能,便于大家日后能”升官发财”。

今天我们就来把基于Redis实现的分布式锁,集成到我们的项目中,分布式锁历来都受到大家的关注。不管是工作中、面试中,分布式锁永远是个不老的话题,也希望大家能掌握此技能,便于大家日后能”升官发财”。

分布式锁

背景

为什么要有分布式锁呢?不是已经有synchronized、ReantrantLock等相关锁了吗?

是的,我们在开发应用的时候,如果需要对某一个共享变量进行多线程同步访问的时候,可以使用我们学到的锁进行处理,并且可以完美的运行,毫无Bug!

注意:这是单机应用,后来业务发展,需要做集群,一个应用需要部署到几台机器上然后做负载均衡 :

上图可以看到,变量A存在三个 服务器 内存中(这个变量A主要体现是在一个类中的一个成员变量,是一个有状态的对象),如果不加任何控制的话,变量A同时都会在分配一块内存,三个请求发过来同时对这个变量操作,显然结果是不对的!即使不是同时发过来,三个请求分别操作三个不同内存区域的数据,变量A之间不存在共享,也不具有可见性,处理的结果也是不对的!

如果我们业务中确实存在这个场景的话,我们就需要一种方法解决这个问题!

为了保证一个方法或属性在高并发情况下的同一时间只能被同一个线程执行,在传统单体应用单机部署的情况下,可以使用并发处理相关的功能进行互斥控制。但是,随着业务发展的需要,原单体单机部署的系统被演化成分布式集群系统后,由于分布式系统多线程、多进程并且分布在不同机器上,这将使原单机部署情况下的并发控制锁策略失效,单纯的应用并不能提供分布式锁的能力。为了解决这个问题就需要一种跨机器的互斥机制来控制共享资源的访问,这就是分布式锁要解决的问题!

分布锁的基本原理

分布式环境下,多台机器上多个进程对同一个共享资源(数据、文件等)进行操作,如果不做互斥,就有可能出现“余额扣成负数”,或者“商品超卖”的情况。

为了解决这个问题,需要分布式锁服务。首先,来看一下分布式锁应该具备哪些条件。

目前市面上,分布式锁的实现方案大致有三种:

项目中,使用的最多的是后两种,其实每种方案都各有利弊。

预防死锁

我们看下面这个典型死锁场景。

一个客户端获取锁成功,但是在释放锁之前崩溃了,此时该客户端实际上已经失去了对公共资源的操作权,但却没有办法请求解锁(删除 Key-Value 键值对),那么,它就会一直持有这个锁,而其它客户端永远无法获得锁。

我们的解决方案是:在加锁时为锁设置过期时间,当过期时间到达,Redis 会自动删除对应的 Key-Value,从而避免死锁。需要注意的是,这个过期时间需要结合具体业务综合评估设置,以保证锁的持有者能够在过期时间之内执行完相关操作并释放锁。

另外,前面已经说了,在实际项目中我们都是使用后两种方案,所以我们重点在后两种方案上。说明 此文章是基于前面我们搞的项目继续开展,同时把Redis已经集成到项目中了,所以此文中分布式锁是基于Redis的实现。

基于Redis实现分布式锁

先说一下使用Redis实现方案的思路:

简单版

创建分布锁

就这样,一个简单的分布式锁就实现了,但是这里会存在问题,问题也不是一定会出现,在特定的时刻还是会出现的。

下面,我们就来把这个分布式锁应用到用户账户余额扣减的功能中。

我们来创建一张用户账户表,表中主要有userId和余额:

然后创建UseraccountRepository接口。

创建UserAccountService和实现类,并实现其扣减方法:

到此,简单版的分布式锁,以及如何使用,这里就已经搞完了。下面我们来理一下思路:

1.使用setnx(set not exist),就是如何set的这个key在redis不存在就返回true,否则返回false。

2.对已经set的key设置有效期,使用expire设置有效期。

3.校验我们的可用余额是否足够扣减,不够就直接结束并使用delete删除redis中的key。

4.扣减余额,更新数据库余额值。

5.删除key,delete redis中key。

那么,问题来了,第一步、第二步都成功了。但假如第三步查询余额、扣减余额耗时20秒了,上面我们对Redis中key的有效期设置的10秒,也就是超时了,key过期了,并且在10秒到20秒之间又有其他线程来获取到锁了,然后此时把其他线程拿到的锁给删了,把其他线程的锁给解了。此时,不就乱了吗?

这也是面试中常被问使用redis做分布式锁,业务超时了怎么办?

升级版

我们可以把每次key对应的value返回,当释放锁的时候,判断当前key对应的value是否是当前手里持有的value。

然后,我们针对上面的进行修改一版。

这里比简单版多了一个判断,判断持有锁的线程是否为当前线程。尽管使用随机字符串的 value来判断是否为当前线程,但是在释放锁时(delete方法),还是无法做到原子操作,比如进程 A 执行完业务逻辑,在准备释放锁时,恰好这时候进程 A 的锁自动过期时间到了,而另一个进程 B 获得锁成功,然后 B 还没来得及执行,进程 A 就执行了 delete(key) ,释放了进程 B 的锁…. ,因此需要配合 Lua 脚本释放锁。

setnx+Lua脚本Lua 是一种轻量小巧的脚本语言,用标准 C 语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。

Lua 提供了交互式编程模式。我们可以在命令行中输入程序并立即查看效果。

lua脚本优点:

在resources目录下创建一个redis-lock.lua文件。填入内容:

这段代码的意思。就是通过key获得其在redis中value,然后使用当前线程手里的value与之对比,一样则删除redis这个key。删除返回1,否则返回0表示什么没做。

Redis锁代码块如下:

最后我们再次执行罚款扣减,日志输出:

到此,setnx+Lua 这种方案我们已经实现了。如果对此有怀疑的,是好事,建议创建多个线程去调用罚款扣减这个service方法,看看器是否会出现问题。

集成Redis分布式锁

「注意」

setnx在redis较低的版本里是没有的,后面才引入的。其实我们也可以使用set命令来解决setnx,另外还可以加过期时间,整体命令为

value 最好是随机字符串,这样可以防止业务代码执行时间超过设置的锁自动过期时间,而导致再次释放锁时出现释放其他进程锁的情况。

setnx 琐最大的缺点就是它加锁时只作用在一个 Redis 节点上,即使 Redis 通过 Sentinel(哨岗、哨兵) 保证高可用,如果这个 master 节点由于某些原因发生了主从切换,那么就会出现锁丢失的情况,下面是个例子:

有的时候甚至不单单是锁丢失这么简单,新选出来的 master 节点可以重新获取同样的锁,出现一把锁被拿两次的场景。

由此可知,锁被获取两次,肯定不能满足安全性了。

尽管前两种方案不是很如意,总是有些问题,但也有被部分企业采用,下面我们就来看基于Redis来实现分布式锁更高级的版本。

高级版 Redisson + RedLock

Redisson 是 java 的 Redis 客户端之一,是 Redis 官网推荐的 java 语言实现分布式锁的项目。

Redisson 提供了一些 api 方便操作 Redis。因为本文主要以锁为主,所以接下来我们主要关注锁相关的类,以下是 Redisson 中提供的多样化的锁:

总之,管你了解不了解,反正 Redisson 就是提供了一堆锁… 也是目前大部分公司使用 Redis 分布式锁最常用的一种方式。

整体加锁和解锁的代码结构如下:

其实,加锁和解锁的磁层也是使用Lua脚本来实现的,有兴趣的朋友可以去翻看一下器底层源码。

由于篇幅问题,还涉及到Redis集群,所以这里就给出加锁和解锁的流程图,仅供参考。

「加锁过程」

「解锁过程」

总结

通常我们为了实现 Redis 的高可用,一般都会搭建 Redis 的集群模式,比如给 Redis 节点挂载一个或多个 slave 从节点,然后采用哨兵模式进行主从切换。但由于 Redis 的主从模式是异步的,所以可能会在数据同步过程中,master 主节点宕机,slave 从节点来不及数据同步就被选举为 master 主节点,从而导致数据丢失,大致过程如下:

ok,然后为了解决这个问题,Redis 作者提出了 RedLock 算法,步骤如下(五步):

在下面的示例中,我们假设有 5 个完全独立的 Redis Master 节点,他们分别运行在 5 台服务器中,可以保证他们不会同时宕机。

获取当前 Unix 时间,以毫秒为单位。

依次尝试从 N 个实例,使用相同的 key 和随机值获取锁。在步骤 2,当向 Redis 设置锁时,客户端应该设置一个网络连接和响应超时时间,这个超时时间应该小于锁的失效时间。例如你的锁自动失效时间为 10 秒,则超时时间应该在 5-50 毫秒之间。这样可以避免服务器端 Redis 已经挂掉的情况下,客户端还在死死地等待响应结果。如果服务器端没有在规定时间内响应,客户端应该尽快尝试另外一个 Redis 实例。

客户端使用当前时间减去开始获取锁时间(步骤 1 记录的时间)就得到获取锁使用的时间。当且仅当从大多数(这里是 3 个节点)的 Redis 节点都取到锁,并且使用的时间小于锁失效时间时,锁才算获取成功。

如果取到了锁,key 的真正有效时间等于有效时间减去获取锁所使用的时间(步骤 3 计算的结果)。

如果因为某些原因,获取锁失败(没有在至少 N/2+1 个Redis实例取到锁或者取锁时间已经超过了有效时间),客户端应该在所有的 Redis 实例上进行解锁(即便某些 Redis 实例根本就没有加锁成功)。

到这,基本看出来,只要是大多数的 Redis 节点可以正常工作,就可以保证 Redlock 的正常工作。这样就可以解决前面单点 Redis 的情况下我们讨论的节点挂掉,由于异步通信,导致锁失效的问题。

但是细想后, Redlock 还是存在如下问题:

假设一共有5个Redis节点:A, B, C, D, E。设想发生了如下的事件序列:

哎,还是不能解决故障重启后带来的锁的安全性问题…

针对节点重后引发的锁失效问题,Redis 作者又提出了 延迟重启 的概念,大致就是说,一个节点崩溃后,不要立刻重启他,而是等到一定的时间后再重启,等待的时间应该大于锁的过期时间,采用这种方式,就可以保证这个节点在重启前所参与的锁都过期,听上去感觉 延迟重启 解决了这个问题…

但是,还是有个问题,节点重启后,在等待的时间内,这个节点对外是不工作的。那么如果大多数节点都挂了,进入了等待,就会导致系统的不可用,因为系统在过期时间内任何锁都无法加锁成功。

总之,在 Redis 分布式锁的实现上还有很多问题等待解决,我们需要认识到这些问题并清楚如何正确实现一个 Redis 分布式锁,然后在工作中合理的选择和正确的使用分布式锁。

但为什么又说,有一部分企业采用Redis来实现分布式锁呢?其实实现分布式锁,从中间件上来选,也有 Zookeeper 可选,并且 Zookeeper 可靠性比 Redis 强太多,但是效率是低了点,如果并发量不是特别大,追求可靠性,那么肯定首选 Zookeeper。

关于分布式锁的实现方案,没有绝对的好与坏,没有最好的方案,只有最适合你的业务的方案。

以下两种方案仅供参考:


未来8年后全球最赚钱的职业是什么?

来十大热门职业的薪酬地位压力排行榜行销师理由:行销师是指从事市场分析与开发研究,为企业生产经营决策提供谘询,并进行产品宣传促销的人员。 由於我国市场经济不断完善,市场行销已经渗入到各种各样的企业,人们对市场行销的观念也将有更深的认识,所以对这方面人才的需求将继续看好,并有继续升温的可能。 目前,最为人们所知的是房地产行销师、汽车行销师和保险行销师。 薪酬因行业等外在因素不同而不同。 环境工程师理由:城市快速扩张、市政建设的更高要求和房地产建设的飞速发展,使得我国环境工程师的需求大大增加。 有关资料显示,目前我国环保产业的从业人员仅有13万余人,其中技术人员8万余人。 按照国际通行的惯例计算,我国在环境工程师方面的缺口在42万人。 随著国内房地产行业的发展,目前国内园林设计师、景观设计师的月薪都在七八千元左右。 据预测,年收入应在8万元至10万元人民币。 精算师理由:精算师是经过金融保险监管部门认可其从业资格的个人。 凡是需要处理风险的领域,精算师都能发挥作用。 与会计师、律师和医生等职业相比,精算师是一项人数不多、专业性更强的职业。 据预测,到2010年,中国将会至少有60家国内保险公司和20家含外资的保险公司。 而目前精算师的数量还远不能满足中国保险业的发展需要。 业内人士称,我国被世界保险界认可的精算师不足10人,“准精算师”40多人,在目前国内人才市场上,精算师可谓凤毛麟角。 目前,精算师在国外的平均年薪达10万美元,国内目前月薪也在1万元人民币以上。 据预测,几年后其收入应在12万元至15万元人民币。 医药销售中西医师理由:全球现代医药技术产业继续呈高速增长态势,现代生物技术产业已经成为医药产业新的国际竞争焦点。 同时,人口的老龄化和人们生活的日益富裕,使医疗卫生成为21世纪初最赚钱的职业之一。 有专家指出,不仅是医生和护士,营养学家、家庭护士、维生素制造商、按摩师和针灸师都将成为热门职业。 目前的医药行业月薪水准在三到五千元人民币,预计4年之后会有一个更好的薪金水准。 据预测,年收入至少应在6万元人民币左右。 管理谘询师理由:管理谘询师针对企业运用管理学的原理,进行从战略策划到战术运用的系列顾问活动,包括对企业CIS、人力资源、流程再造、组织结构设计、行销等方面进行策划并指导实施。 专家指出,我国目前管理谘询专业人才严重短缺。 在未来10年中,我国管理谘询业的需求将以每年10倍的速度增加,到2010年中国管理谘询行业的有效需求总额将达到100亿美元。 管理谘询师年薪大约在10万到60万元人民币不等。 未来几年乃至十几年之内,什麼样的职业最受追捧?近日,业内知名人力资源专家从职业的薪酬指数、社会地位指数、压力指数等几方面,对未来热门职业进行综合评价。 理财规划师理由:资料显示,预计2006年中国个人理财市场将增长到570亿美元,并且以每年10%至20%的速度增长。 目前,一方面社会对金融理财的需求非常急迫,市场需求潜力巨大;另一方面,理财产品明显捉襟见肘。 理财师,尤其是能够为客户提供全方位的专业理财建议,通过不断调整存款、股票、债券、基金、保险、动产、不动产等各种金融产品组成的投资组合,设计合理的税务规划,满足居民长期的生活目标和财务目标的人才,更是难求。 专家预计,我国理财规划师的缺口为20万人。 未来5到10年,理财规划师将成为国内最具有吸引力的职业。 有专家认为,国内理财规划师的年薪应该在10万到100万元人民币之间。 系统集成工程师理由:“十五”期间是我国电子资讯产业发展的关键时期,预计电子资讯产业仍将以高於经济增速两倍左右的速度快速发展,产业前景十分广阔。 目前,资讯技术支援人才需求中排除技术故障、设备和顾客服务、硬体和软体安装以及配置更新和系统操作、监视与维修等四类人才最为短缺。 此外,电子商务和互动媒体、数据库开发和软体工程方面的需求量也非常大。 从总体上看,IT人才的需求每年将增加100万。 专家估计,国内系统集成工程师年收入将在10万至20万元。 未来网路专才尤其是网路游戏业人员的薪酬将会达到10万元至12万元人民币。 律师理由:律师一直是我国近年来比较热门的职业。 未来几年也仍将是受追捧的热门职业之一。 据不完全统计,目前我国取得律师资格的专职律师还不到2万人,平均每10万人口只有两名律师,而聘请律师的企业也只占全部企业的千分之几,无论是数量还是品质都远远不能适应社会的需求。 而目前,我国律师队伍中高层次、高技能、复合型人才短缺,从事国际性律师业务的专门知识和服务经验不足,在涉外法律服务市场的竞争力较弱。 律师的年收入在10万到80万元人民币之间。 物流师理由:物流业是当代经济发展的热点,涵盖了国民经济中的海陆空交通、运输、仓储、采购、供应、配送、流通加工、资讯、第三方物流、连锁销售、制造业以及与物流相关的众多行业。 目前,我国物流人才供不应求。 物流从业人员当中拥有大学学历以上的仅占21%。 许多物流部门的管理人员是半路出家,很少受过专业的培训。 据初步估算,我国物流人才的需求量为600余万人。 结合国外的情况看,未来几年我国物流师中、高层管理人员的年薪将达到15万到40万元人民币左右。 注册会计师理由:目前,我国共有注册会计师7万多名。 而根据中国经济高速发展的需要,至少急需35万名注册会计师。 就是在已具备从业资格的7万多名注册会计师中,被国际认可的不足15%。 巨大的需求缺口,使注册会计师成为未来几年我国炙手可热的人才。 有关人士称,每年进入包括德勤、毕博在内的四大会计师事务所的应届毕业生月薪大都在五六千元,再加上每年丰厚的奖金,年收入会超过10万元人民币。 中高层管理人员的年薪则在20万到50万元人民币之间。

雷雨天气,如何注意安全?有什么需要注意的?

夏季是雷雨多发季节,容易出现家用电脑因而雷击造成电脑硬件的损坏和通讯故障,为了避免这种情况的的发生,保护您的财产不受损失,建议您继续阅读下面内容:雷击一般分为直击雷和感应雷,建筑物安装避雷针只能防范直击雷,而感应雷则通过外部相连的线路危害室内的家用电器,特别是电脑。 因此,雷雨天注意防雷是必要的。 下面的防雷方法供大家参考:1、要注意经常定期检查电脑所使用的接地线。 大多数电脑的外壳几乎都与这条接地线相连,其主要目的是对人身安全起保护作用,此外地线还可以消除静电对设备的影响。 2、电脑与建筑物的外墙及柱子要保持一定距离。 特别是城市内的高层建筑,柱内有大量钢筋。 因为当您所住的建筑物发生直击雷或侧击雷时,强大的雷电流将沿着建筑物的外墙及柱子流入地下。 在这个过程中,由于建筑物的外墙或柱子有强大的雷电流流过,便在周围的空间产生电场和磁场,如果电脑与外墙或柱子靠得太近,电脑内的集成电路模块则有可能受到损坏。 3、雷雨天气尽量不要上网,因为雷击可能通过电源线引入,把MODEM烧坏,甚至将计算机的网卡、主板等器件烧坏。 4、即使是没有直接引入雷电,一般情况下,网卡、modem、及电脑电源也容易在雷雨天气下损坏,其原因是设备直接连接有较长的线路,类似于收音机天线,对雷电空间电磁场感应较敏感,集成电路模块容易在瞬间感应高压下损坏、损伤(在后续的一星期内发生故障)。 5、在雷雨来临之际,尽可能把各种与电脑相连的线路(包括电源线、网线、电话线等)拔掉。 虽然您家里不一定安装了专业的防雷设施,但是只要从以上小事做起,就能最大限度保护电脑的安全,减少雷电带来损失。

选什么专业好找工作?

1. 电子信息 电子信息产业是一项新兴的高科技产业,被称为朝阳产业,产业前景十分广阔。 未来的发展重点是电子信息产品制造业、软件产业和集成电路等产业;新兴通信业务如数据通信、多媒体、互联网、电话信息服务、手机短信等业务也将迅速扩展;值得关注的还有文化科技产业,如网络游戏等。 此外,电子商务和互动媒体、数据库开发和软件工程方面的需求量也非常大。 2.生物技术 21世纪是生物的世纪,生物科技经济发展起来是必然趋势。 生物科研人才近年来一直是国际人才竞争的焦点之一。 随着基因技术、生物工程等领域的发展和产业升级,这类高技术专业人才的缺口会越来越大。 3.医药类 全球现代医药技术产业继续呈高速增长态势,现代生物技术产业已经成为医药产业新的国际竞争焦点。 科技部已将“创新药物与中药现代化”列为“十五”期间国家12个重大科技专项之一。 4.汽车类 随着汽车逐渐成为我们生活中的必需品,汽车专业也成为了社会上十分走俏的专业。 汽车类专业人才成为了炙手可热的“抢手货”。 此外,热能与动力工程、工业设计等相关专业人才需求也将持续看涨。 5.物流类 随着公路货运、仓储、海上搬运运输、船舶代理等方面进一步开放市场,相关行业和企业与国外物流企业将开展全面合作,现代物流将进入快速增长、全面发展的新时期。 6.材料类 新材料的应用范围非常广泛,发展前景十分广阔,其研发水平及产业化规模已成为衡量一个国家经济发展、科技进步和国防实力的重要标志。 同时,国内支柱产业及高技术产业发展对新材料的需求不断扩大。 7.环境能源类 环保产业有着巨大的发展潜力。 随着环境保护投入的大幅度增加,环保产业发展较快,成为国民经济的重要组成部分。 环保产业的发展之快,效益之显著,无疑是环保技术人员的研究与开发的结果。 8.管理类 因为加入WTO和申奥成功将直接带动外经外贸的大发展,所以,管理类专业人才社会需求大增将指日可待。 9.法律类 目前我国律师人才十分缺乏。 据不完全统计,目前我国取得律师资格的专职律师还不到2万人,同时,随着全民的法律意识逐渐在增强,企业的法律意识也在增强,对法律专业人才的需求将会大大提高。 法律专业因此成为未来热门专业之一。 10.营销类 由于我国市场经济不断完善,市场营销已经渗入到各种各样的企业,人们对市场营销的观念也将有更深的认识,所以对这方面人才的需求将继续看好,并有继续升温的可能。 其中最好的就是房产推销员,汽车营销人员,保险推销人员。

本文版权声明本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请联系本站客服,一经查实,本站将立刻删除。

发表评论

热门推荐