
本文已收录在Github,关注我,紧跟本系列专栏文章,咱们下篇再续!
除了“持有锁的进程崩溃、未释放锁”这一经典场景,还会因以下容易被忽视的问题,导致系统进入类似死锁的阻塞状态:
若加锁客户端的系统时间被人为或自动回拨,可能导致锁的本地过期时间计算错误,客户端误以为锁已过期而提前续期或释放,其他客户端趁机抢占,造成多客户端同时持有同一把锁,后续释放时又互相覆盖,最终谁都无法正常完成业务,表现得像死锁。
启用 NTP 严格同步,或使用 monotonic 时间源;
Redisson“看门狗”机制依赖后台线程周期性地为锁续期。若业务线程因 GC、CPU 调度或网络抖动被长时间挂起,看门狗线程也随之暂停,锁在 Redis 端真正过期;业务恢复后却仍认为锁有效,继续持有,导致后续竞争者无法获取锁,形成阻塞。
限制业务逻辑执行时间,设置合理的 watchdog 超时上限。
Redis主从异步复制下:
新客户端在新【主节点】上再次加锁成功,两个客户端同时持有同一把锁;当它们都尝试释放锁时,可能互相删除对方的键,造成业务逻辑混乱,后续请求因锁状态不一致而持续等待。
启用 Redis 哨兵或集群模式,结合 RedLock 多数派策略。
用 Lua 脚本保证“判断-删除”原子性时,若脚本因数据量过大或逻辑复杂执行时间超过 Redis 的 lua-time-limit,Redis 会中断脚本并记录 EVALSHA 失败,但客户端可能未收到失败信号,继续认为锁已释放;其他客户端因键仍存在而无法加锁,系统出现“假死”状态。
拆分复杂脚本,缩短执行时间,或改用 pipeline 分批执行。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。