一、从本地锁到分布式锁:为什么需要跨越进程边界?
1. 本地锁的局限性
// 本地锁示例(单JVM有效)
public class OrderService {
private final ReentrantLock lock = new ReentrantLock();
public void checkStock() {
lock.lock();
try {
// 检查库存逻辑
} finally {
lock.unlock();
}
}
}
痛点场景:
- 订单服务集群化部署(3个实例)
- 用户同时发起多个下单请求
- 本地锁无法跨JVM互斥 → 导致超卖
2. 分布式锁的核心价值
二、分布式锁的四大实现方案深度对比
1. 技术方案全景图
实现方式 | 核心原理 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|
数据库 | 唯一约束/乐观锁 | 实现简单 | 性能差、无失效机制 | 低频简单场景 |
Redis | SETNX+过期时间 | 性能优异 | 需处理锁续期 | 高频读场景 |
ZooKeeper | 临时有序节点 | 可靠性高 | 性能中等 | CP系统 |
ETCD | Lease租约机制 | 强一致性 | 复杂度高 | 金融级系统 |
2. Redis分布式锁演进之路
第一代:SETNX基础版
SET lock_key random_value NX EX 30
缺陷:
- 非原子操作
- 锁续期问题
- 误删其他线程锁
第二代:Redisson实现
// 使用Redisson客户端
RLock lock = redisson.getLock("order_lock");
try {
lock.lock();
// 业务逻辑
} finally {
lock.unlock();
}
核心优化:
- WatchDog自动续期
- Lua脚本保证原子性
- 可重入设计
三、ZooKeeper分布式锁实现原理
1. 临时顺序节点机制
2. 代码实现示例
public class ZkLock {
private CuratorFramework client;
private InterProcessMutex lock;
public ZkLock(String lockPath) {
client = CuratorFrameworkFactory.newClient("zk-host:2181");
client.start();
lock = new InterProcessMutex(client, lockPath);
}
public boolean tryLock(long timeout, TimeUnit unit) {
return lock.acquire(timeout, unit);
}
public void unlock() {
lock.release();
}
}
四、生产环境最佳实践
1. 锁特性保障方案
要求 | 实现方案 | 风险应对 |
---|---|---|
互斥性 | Redis原子SETNX/ZK节点唯一 | 网络分区时使用Redlock |
可重入 | ThreadLocal记录持有计数 | 防止重复解锁 |
锁超时 | 看门狗机制+合理TTL设置 | 避免GC停顿导致锁失效 |
容错性 | 多节点部署+故障自动转移 | 使用ETCD等强一致性存储 |
2. 锁监控体系搭建
// 锁监控指标示例(Micrometer)
Metrics.counter("distributed.lock.acquire.count",
"type", "redis").increment();
Metrics.timer("distributed.lock.hold.time",
"type", "redis").record(() -> {
// 业务逻辑
});
五、经典问题与解决方案
案例1:锁永久失效
现象:
- Redis主从切换导致锁丢失
- 多个客户端同时持有锁
解决方案:
- 采用Redlock算法(至少3个独立Redis实例)
- 使用ZooKeeper临时节点
案例2:锁续期失败
现象:
- 业务处理时间超过锁TTL
- 自动续期线程被阻塞
优化方案:
// Redisson看门狗机制
Config config = new Config();
config.setLockWatchdogTimeout(30000); // 30秒续期周期
六、方案选型指南
决策树分析
推荐组合
- 电商秒杀:Redis+Redisson
- 资金交易:ZooKeeper+Curator
- 配置中心:ETCD Lease
七、未来演进方向
- 无锁化设计:CRDT冲突解决算法
- 混合锁机制:本地锁+分布式锁分级保护
- 云原生锁服务:基于Service Mesh的全局锁