
1. 分布式锁服务核心概念解析分布式锁是分布式系统中协调多节点对共享资源访问控制的基础设施。当多个服务实例需要互斥访问数据库某条记录、文件系统某个文件或执行某个特定操作时分布式锁能确保同一时刻只有一个实例获得操作权限。我在金融支付系统架构设计中曾遇到这样的典型场景当用户发起提现请求时后端需要检查账户余额扣减金额生成交易记录这三个操作必须作为原子单元执行。在单机环境下用本地锁即可解决但在分布式部署时必须依赖分布式锁来防止并发操作导致超额扣款。这就是分布式锁最经典的应用场景之一。2. 主流分布式锁实现方案对比2.1 基于Redis的实现方案Redis因其高性能和丰富的原子操作命令成为实现分布式锁的首选。最常用的方案是SETNX命令配合过期时间// 加锁示例 String result jedis.set(lockKey, requestId, NX, PX, expireTime); if (OK.equals(result)) { // 获取锁成功 } // 解锁示例 String script if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end; Object evalResult jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));关键注意事项必须设置唯一requestId作为锁值防止误删其他客户端的锁过期时间需要根据业务操作耗时合理设置使用Lua脚本保证解锁操作的原子性2.2 基于Zookeeper的实现方案Zookeeper通过临时顺序节点实现分布式锁客户端在指定路径下创建临时顺序节点判断自己是否是最小序号的节点如果是则获取锁否则监听前一个节点的删除事件public boolean tryLock() { // 创建临时顺序节点 ourPath zk.create(path /lock-, EPHEMERAL_SEQUENTIAL); // 获取所有子节点并排序 ListString children zk.getChildren(path, false); Collections.sort(children); // 判断是否获得锁 int ourIndex children.indexOf(ourPath.substring(path.length() 1)); return ourIndex 0; }Zookeeper方案的优势在于能避免Redis可能存在的锁过期但业务未执行完的问题但性能相对较低。3. 分布式锁的高级特性实现3.1 可重入锁实现可重入特性允许同一个线程多次获取同一把锁。实现时需要记录持有线程和重入次数-- Lua脚本实现可重入锁 local counter redis.call(hincrby, KEYS[1], ARGV[1], 1) if counter 1 then redis.call(pexpire, KEYS[1], ARGV[2]) end return counter3.2 公平锁实现公平锁需要维护一个等待队列常见实现方式使用Redis的List结构作为等待队列每个客户端在队列中注册自己的位置只有队首客户端能获取锁使用发布订阅机制通知下一个客户端4. 生产环境中的典型问题与解决方案4.1 锁续期问题当业务操作时间超过锁的过期时间时可能导致锁提前释放。解决方案是使用守护线程定期续期private void scheduleExpirationRenewal() { Thread renewalThread new Thread(() - { while (!Thread.currentThread().isInterrupted()) { try { // 每1/3过期时间续期一次 Thread.sleep(expireTime / 3); String script if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(pexpire, KEYS[1], ARGV[2]) else return 0 end; jedis.eval(script, Collections.singletonList(lockKey), Arrays.asList(requestId, String.valueOf(expireTime))); } catch (Exception e) { Thread.currentThread().interrupt(); } } }); renewalThread.setDaemon(true); renewalThread.start(); }4.2 集群环境下的锁可靠性在Redis集群环境下主从切换可能导致锁丢失。RedLock算法通过多个独立Redis实例来提高可靠性向N个独立Redis实例顺序请求锁当获得超过半数实例的锁时才算成功锁的有效时间是初始有效时间减去获取锁消耗的时间5. 性能优化实践5.1 锁粒度控制过粗的锁粒度会导致性能下降。建议账户级锁改为交易流水号级锁全局锁改为分段锁如按用户ID哈希分片5.2 锁等待优化长时间等待锁会降低系统吞吐量。可采用快速失败策略获取不到锁立即返回异步回调机制锁释放后通知等待者乐观锁替代使用版本号控制我在实际项目中发现将锁等待超时时间设置为平均业务处理时间的3倍能在保证成功率的同时获得较好的吞吐量。