企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
#### **1.通过SETNX实现互斥** 客户1试图加锁 ~~~ SETNX lock 1 (integer) 1 // 客户端1,加锁成功 ~~~ 客户2试图加锁,失败 ~~~ SETNX lock 1 (integer) 0 // 客户端2,加锁失败 ~~~ #### **2.需要释放锁** 如果有客户端进程挂掉,会造成其他客户端无法获取到锁,进而死锁 ~~~text 127.0.0.1:6379> DEL lock // 释放锁 (integer) 1 ~~~ #### **3.设置锁消亡时间** 设置消亡时间可以避免死锁,但是会出现业务没有完成,锁被强制收回的情况 ``` SET lock 1 EX 10 NX # 加锁和消亡时间由Redis保证原子性 ``` 问题: > 客户1获得锁,并执行业务处理 > 业务处理时锁过期,锁被强制收回 > 客户二获得锁,并执行业务 > 客户一业务执行完成,释放锁,此时是客户2的锁 解决办法,对自己的锁标识 **4. 锁标识** 上锁时,加上自己的唯一标识(锁=key,标识=value),value唯一即可 ~~~ // 锁的VALUE设置为UUID 127.0.0.1:6379> SET lock $uuid EX 20 NX OK ~~~ 解锁时,进行判断 ``` // 锁是自己的,才释放 if redis.get("lock") == $uuid redis.del("lock") ``` 由于get和del不是原子操作,又会产生线程安全问题(概率很小) > 首先,客户1判断是自己的锁,此时锁被强制收回 > 客户2获取锁 > 客户一继续删除,又删错了 解决办法,通过lua脚本让get和del指令具有原子性 #### **5.锁存活时间问题** 业务没有执行完成,锁被强制收回,如何控制好锁消亡时间,redisson有看门狗技术,实时监控业务处理