关于Redisson实现分布式锁

文章介绍了分布式锁在微服务架构中的重要性,详细阐述了如何利用Redis的setnx命令实现锁的获取与释放,并讨论了设置锁过期时间来避免死锁的问题。此外,文章提到了Redisson如何通过后台线程动态延长锁的生命周期,以解决锁过早释放导致的问题。在集群环境中,文章提到可能需要结合Lua脚本使用。
摘要由CSDN通过智能技术生成

一. 前言

为什么需要分布式锁?

在微服务架构下.多个应用服务同时对同一条数据做修改(例如:秒杀扣减库存),为了保证数据的正确性,我们需要保证某个时间内,只可以有一个应用修改,这时候就用到了分布式锁。

二. 基于Redis实现分布式锁

为什么Redis可以实现分布式锁?

因为Redis是一个单独的非业务服务,不会受到其他服务的限制,所有的服务都可以向Redis发送请求,且只有一个服务可以写入命令成功,当这个服务写入成功时会获得锁,可以进行后续的对资源的操作,此时其他服务写入命令会失败,得不到锁。

如何实现

Redis的String类型就可以实现,没有线程安全问题。

锁的获取

setnx key value命令:表示SET if Not eXists,即如果key不存在,才会设置值为value,否则什么都不做

当多个客户端同时向Redis写入try_lock,只有一个会成功,会获取分布式锁成功,返回1在这里插入图片描述
其他的客户端会失败,返回0在这里插入图片描述

锁的释放

当获得锁的客户端执行完后续操作时,释放锁资源,即删除try_lock在这里插入图片描述

那么此时其他客户端在次获取锁时就会成功,就可以执行后续任务

但是这样还有有新的问题:
假如客户端1在获取到锁资源后,服务宕机了,那么这个try_lock会一直存在redis中,那么其他服务就永远无法获取到锁了,形成死锁。

三. 如何避免死锁?锁的过期时间如何设置

设置键过期时间,超过这个时间即给key删除掉。
这样的话,就算当前服务获取到锁后宕机了,这个key也会在一定时间后被删除,其他服务照样可以继续获取锁。
给serverLock键设置一个10秒的过期时间,10秒后会自动删除该键。在这里插入图片描述
这样虽然解决了上面说的问题,但是又会有新的问题。

假如客户端1加锁成功,锁会在10s后自动释放,但由于业务复杂,执行时间过长,10s内还没执行完,此时锁已经被redis自动释放掉了。此时客户端2就重新获取到了该锁,客户端2开始执行他的业务,客户端1在执行到第15s的时候执行完了,那么客户端1会去释放锁,则此时释放的却是客户端2刚获取到的锁。

这样会有锁过期和释放其他服务锁这种严重的问题,Redisson很好的解决了这个问题。

四.Redisson实现分布式锁

在这里插入图片描述
当一个线程1获取锁成功时,Redisson会再开启一个后台线程,每隔一段时间(设置的过期时间的1/3)就会检查当前线程1是否还持有锁,如果持有就会延长锁的时间,此时线程2来获取锁,判断能否加锁成功,失败就会一直尝试加锁,当线程1执行完成后,再释放锁,线程2就可以拿到锁去执行后续任务

具体实施步骤:

  • 导入Redisson依赖
    在这里插入图片描述
  • 注册一个Redisson在这里插入图片描述
  • 加锁,设置过期时间(try)在这里插入图片描述
  • 释放锁(finale)
    在这里插入图片描述
    注: 以上是基于Redis单机,在集群情况下还需结合Lua脚本实现(小编暂时不会,有需要自行百度)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hyde_jn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值