news 2026/9/15 14:23:15

分布式锁的七种写法:从 SetNX 到 Redisson 看门狗 (WatchDog),谁才是最终答案?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
分布式锁的七种写法:从 SetNX 到 Redisson 看门狗 (WatchDog),谁才是最终答案?

🔒 前言:面试官的陷阱

“请手写一个 Redis 分布式锁。”
如果你直接写了redis.setnx(key, 1),面试官可能会让你直接回家等通知。

为什么?

  • 如果服务器宕机,锁没释放怎么办?(死锁)
  • 如果你加了过期时间,但业务执行时间超长怎么办?(锁失效)
  • 如果你释放了别人的锁怎么办?(并发安全)

今天,我们像剥洋葱一样,从青铜到王者,拆解分布式锁的7 种进化形态


👶 第一阶段:青铜时代 (漏洞百出)

写法一:裸奔的setnx
// 1. 抢锁if(redis.setnx(lockKey,1)==1){try{// 业务逻辑...}finally{// 2. 释放锁redis.del(lockKey);}}
  • 致命死穴:如果业务逻辑执行到一半,服务器宕机了/重启了finally没执行,锁永远删不掉。造成永久死锁!
写法二:setnx+expire
if(redis.setnx(lockKey,1)==1){redis.expire(lockKey,30);// 补一个过期时间try{...}finally{redis.del(lockKey);}}
  • 致命死穴setnxexpire是两条命令,不是原子的。如果刚 setnx 完,网线被拔了,expire 没执行,依然死锁!

🥈 第二阶段:白银时代 (原子性解决)

写法三:SET NX PX(Redis 2.6.12+)

Redis 官方终于看不下去了,把设置值和过期时间合并成了一条命令。

// 原子命令:SET lockKey requestId NX PX 30000Stringresult=jedis.set(lockKey,requestId,"NX","PX",30000);if("OK".equals(result)){try{...}finally{redis.del(lockKey);}}
  • 潜在问题:解决了死锁,但还有一个大坑——误删锁
    1. A 拿到锁,过期时间 30s。
    2. A 业务卡顿,跑了 40s。此时锁自动过期,B 拿到了锁。
    3. A 跑完了,执行finally里的del把 B 的锁给删了!
    4. C 趁虚而入,B 和 C 同时在跑,线程不安全。
写法四:UUID + Lua 脚本 (校验身份)

为了防止删错锁,我们在 Value 里存一个 UUID (Client ID)。删除前判断一下:这是不是我的锁?

-- Lua 脚本保证原子性ifredis.call('get',KEYS[1])==ARGV[1]thenreturnredis.call('del',KEYS[1])elsereturn0end
  • 依然痛点:虽然不删别人的锁了,但 A 的业务还没跑完锁就过期了,A 依然是在“裸奔”(并发执行)。我们需要**“锁续期”**。

🥇 第三阶段:黄金时代 (Redisson 看门狗)

写法五:手动写守护线程 (太累)

你自己写一个 Timer,每隔 10秒 检查一下,如果 A 还在跑,就给锁续命。
但是,写好这个多线程逻辑极其复杂,很容易由“解决死锁”变成“制造死锁”。

写法六:Redisson (工业级标准)

Redisson是 Redis 官方推荐的 Java 客户端,它内置了一个神器——看门狗 (WatchDog)

使用代码(极其优雅):

RLocklock=redisson.getLock("myLock");try{// 1. 加锁 (默认 30s 过期,自动启动看门狗)lock.lock();// 2. 业务逻辑 (哪怕跑 1 小时,锁也不会断)Thread.sleep(60*60*1000);}finally{// 3. 解锁 (自动停止看门狗)lock.unlock();}

看门狗原理图解:

看门狗续期机制
1. 尝试加锁 (SET NX PX)
2. 加锁成功
3. 启动 WatchDog (后台线程)
4. 每隔 10s (lockWatchdogTimeout/3)
是 (业务未完)
6. 业务结束 unlock()
7. 停止 WatchDog
检测锁还在吗?
看门狗任务
5. 重置过期时间为 30s
Redis 服务端
客户端线程 A

WatchDog 核心逻辑:

  1. Redisson 只要加锁成功,就会启动一个后台定时任务(TimeTask)。
  2. 默认每隔10秒(默认过期时间 30s 的 1/3) 检查一次。
  3. 如果当前线程还持有锁,就通过 Lua 脚本把 Redis 里的过期时间重置为 30s。
  4. 如果服务器宕机,看门狗线程也挂了,没人续期,Redis 里的锁 30s 后自动失效,不会死锁。完美!

👑 第四阶段:王者时代 (RedLock 红锁)

写法七:RedLock (解决主从一致性)

场景

  1. A 在 Redis Master 拿到了锁。
  2. Master 还没来得及把数据同步给 Slave,Master 挂了。
  3. Slave 升级为 New Master。
  4. B 在 New Master 也可以拿到锁。
    结果:A 和 B 同时持锁。

为了解决这个极端问题(虽然概率极低),Redisson 实现了RedLock算法。

  • 原理:搞 5 个独立的 Redis 节点(不是集群,没有主从)。
  • 规则:客户端同时向这 5 个节点申请锁,只要N/2 + 1 (即 3 个)节点加锁成功,就认为获取锁成功。
RLocklock1=redisson1.getLock("lock");RLocklock2=redisson2.getLock("lock");RLocklock3=redisson3.getLock("lock");RedissonRedLocklock=newRedissonRedLock(lock1,lock2,lock3);lock.lock();

(注:RedLock 性能较差,且存在时钟跳变问题,业界争议较大,一般业务场景不推荐使用。)


📝 总结:谁才是最终答案?

在 99% 的业务场景下(电商秒杀、库存扣减、定时任务不重跑),Redisson 的默认锁(写法六)就是最终答案

它完美解决了:

  1. 死锁(宕机自动过期)
  2. 原子性(Lua 脚本)
  3. 误删(UUID 校验)
  4. 业务超时(WatchDog 自动续期)

除非你是在做“金融级核心转账”,否则不要去碰 RedLock,过度设计是万恶之源。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 9:49:59

Apache Mesos集群运维实战:故障恢复与版本管理完全指南

Apache Mesos集群运维实战:故障恢复与版本管理完全指南 【免费下载链接】mesos Apache Mesos 项目地址: https://gitcode.com/gh_mirrors/mesos2/mesos 在现代分布式系统中,Mesos集群维护是确保业务连续性的关键环节。本指南将深入解析Mesos集群运…

作者头像 李华
网站建设 2026/9/15 9:51:23

探索式测试的Session管理法:提升软件测试效率与可追溯性

探索式测试作为一种强调测试者自主性与创造性的软件测试方法,在快速迭代的现代开发环境中日益重要。然而,其非结构化的特性可能导致测试过程难以追踪和评估。Session管理法应运而生,它通过引入时间盒(Time-boxed)会话和…

作者头像 李华
网站建设 2026/9/15 1:16:38

购物省钱参考:爱创猫电商优惠券领取方式

外卖网购“隐形开支”太多?这份极致省钱手册,让你每月轻松多省几百块你有没有算过,自己每个月花在外卖和网购上的钱有多少?打开手机账单,那些十几二十块的外卖订单,几十上百的“凑单”商品,看似…

作者头像 李华
网站建设 2026/9/14 16:44:24

12、Red Hat Enterprise Linux硬件分析与管理指南

Red Hat Enterprise Linux硬件分析与管理指南 1. RPM包安装与信息查看 在安装示例包时,如果未安装 vpnc 包,会显示如下错误: error: Failed dependencies: vpnc is needed by startvpn-1.1-1.noarch若要强制安装该包以测试从示例中构建的软件包,可使用以下命令: r…

作者头像 李华
网站建设 2026/9/15 8:21:45

35、Linux 内核监控与调试:NUMA、AltSysRq 及 Kdump 全解析

Linux 内核监控与调试:NUMA、AltSysRq 及 Kdump 全解析 在 Linux 系统的运维和管理中,对内核的监控与调试至关重要。本文将深入探讨 NUMA 统计信息、AltSysRq 系统请求以及 Kdump 内核转储工具的使用,帮助你更好地理解和管理 Linux 内核。 1. NUMA 统计信息 NUMA(Non-Un…

作者头像 李华
网站建设 2026/9/14 16:48:14

DataEase开源BI工具完整指南:从零开始的数据可视化之旅

DataEase开源BI工具完整指南:从零开始的数据可视化之旅 【免费下载链接】DataEase 人人可用的开源 BI 工具 项目地址: https://gitcode.com/feizhiyun/dataease DataEase是一款人人可用的开源BI工具,让数据分析变得简单直观。作为一款基于GPLv3协…

作者头像 李华