分布式系统里,多个进程抢同一资源,单机锁(synchronized)失灵。怎么保证"同一时刻只有一个能改"?
公众号聊天框回复关键字0930获取Java面试速通20篇合集!一、为什么需要
订单服务部署多台机器,都用 synchronized 只锁住自己 JVM,别的机器照样改——超卖就这么来的。需要一把跨进程的锁。
二、方案 1:数据库唯一索引
建一张锁表,对某资源唯一键 INSERT,成功即拿到锁,释放就 DELETE。
- 优点:简单。缺点:无超时易死锁、性能差、DB 压力大。
三、方案 2:Redis(最常用)
SET lock_key uuid NX EX 30:不存在才设(NX),带 30 秒过期(EX),值用 uuid 防止误删别人的锁。
释放锁要用 Lua 脚本保证"判断是自己 + 删除"原子。
- 坑:1) 锁提前过期,业务没跑完 → 用看门狗自动续期(Redisson 已做);2) 主从切换丢锁 → RedLock 有争议,慎用。
四、方案 3:ZooKeeper
创建临时有序节点,最小序号的持锁;释放断开会话节点自动删,天然防死锁。
- 优点:可靠、自动释放。缺点:性能不如 Redis,依赖 ZK 集群。
五、怎么选
- 要求高可用、能容忍极小概率丢锁 → Redis(主流)
六、面试速记
- Redis 用 SET NX EX + uuid + Lua 释放。
七、一句话带走
Redis 一把锁:SET NX EX 加锁、uuid+Lua 释放、看门狗续期;要强一致上 ZK。别手写 del 释放锁。
系统设计面试
更多 Java 面试速通,关注公众号持续更新。
公众号聊天框回复关键字0930获取Java面试速通20篇合集!