锁 TTL 到期但业务未结束如何处理,WatchDog 如何续期?
未标记
考查重点:租期续约与旧执行者隔离。业务未完锁到期可并发进入,Watchdog 到期前续租;还需业务超时和旧执行者隔离,防无限续卡死
本题目录
参考答案
本答案基于相关资料,由 AI 辅助编写,供学习与面试准备参考。如有疏漏,欢迎反馈指正。
核心回答
锁的 TTL 到期后,其他执行者就可能获得同一资源的锁,而旧执行者的业务代码不会因此自动停止。因此业务仍在执行时锁过期,会出现两个执行者同时访问资源的风险。
看门狗在租约结束前确认持有者仍有效,并延长锁的过期时间,避免正常长任务提前失锁。它解决的是租约存活问题,不等于永久互斥:长时间暂停、网络分区或续约失败后,旧任务仍可能恢复执行。关键写入要用版本条件或资源端支持的 fencing token 拒绝迟到操作。
续约怎样安排
初始租期要覆盖正常执行和合理抖动,续约在到期前留出余量。续约必须原子地校验持有者身份并更新过期时间,不能看到键存在就给别人续租;释放也必须校验身份。
以 Redisson RLock 为例,不指定显式租期的常用加锁方式可启用看门狗,默认看门狗超时为三十秒;显式设置 leaseTime 时按固定租期释放,不能再假设自动续约。实际调度与异常行为还要以所用版本为准。
如何处理失锁与卡死
任务设置业务截止时间、外部请求超时和取消机制;续约失败时停止继续发起受保护操作,检查关键写入结果。线程还活着不代表业务在推进,因此不能把持续续租当成健康检查。
如果执行者在暂停后无法及时知道自己已经失锁,只在写入前查询一次锁也存在检查与使用之间的竞态。更严格的方案是在每次获得锁时生成单调递增令牌,下游原子拒绝旧令牌;下游不校验令牌,单独生成一个数字并不能提供隔离。
同时考虑唯一约束、状态机与幂等。它们保护业务结果,不能被一条自动续期配置代替。
对应教程
- 第16章:记忆与对话历史,Redis 基本命令:回看
TTL与EXPIRE的基本含义;锁的持有者校验、续约和失锁隔离在本文展开。
参考资料
- 国内:JavaGuide:分布式锁:采用锁租约失效与业务条件约束分开的分析,解释续约不能替代资源端的旧写入隔离。
- 国内:JavaGuide:分布式锁实现方案:采用租期、续约与失效风险的解释,说明暂停后的旧执行者仍需隔离。
- 国内:阿里云:基于TairString实现分布式锁:核对加锁随机值、原子校验后释放与续租,避免误操作其他持有者。
- 国内:阿里云:Redis开发运维规范:参考客户端需要对超时和慢请求做容错的约束,解释续约之外仍需业务截止时间与外部调用超时。
- 国外:Redis:Distributed Locks:核对租期和随机持有者值的作用,以及故障切换时互斥保证的边界。
- 国外:Redisson:Locks and synchronizers:核对
RLock持有者、看门狗与显式leaseTime的区别,解释固定租期不能默认获得自动续约。


