2025/12/26 11:02:11
网站建设
项目流程
景点旅游网站开发与设计,织梦小说网站模板下载,京东商城官方网站,上上海网站建设设计在微服务架构或分布式系统中#xff0c;Java 内置的锁#xff08;如 synchronized 或 ReentrantLock#xff09;只能限制当前 JVM 内部的线程互斥。当我们需要跨多个服务节点、跨进程地去抢占同一个资源#xff08;如“扣减库存”、“抢单”#xff09;时#xff0c;就需…在微服务架构或分布式系统中Java 内置的锁如synchronized或ReentrantLock只能限制当前 JVM 内部的线程互斥。当我们需要跨多个服务节点、跨进程地去抢占同一个资源如“扣减库存”、“抢单”时就需要引入分布式锁。本文将深入对比业界常见的三种分布式锁实现方案MySQL、Redis和ZooKeeper解析其原理、代码实现及优缺点。一、基于 MySQL 实现分布式锁MySQL 实现分布式锁主要利用了数据库的唯一性约束或排他锁X锁特性。1. 方案 A基于唯一索引 (Unique Index)这是最直观的方法。我们创建一个锁表并对lock_key字段加上唯一索引。加锁执行INSERT INTO lock_table (lock_key) VALUES (order_101);。如果插入成功则获取锁如果报Duplicate Key Error则获取失败。解锁执行DELETE FROM lock_table WHERE lock_key order_101;。2. 方案 B基于排他锁 (SELECT ... FOR UPDATE)利用 MySQL 的事务机制通过FOR UPDATE对某一行数据加排他锁。START TRANSACTION; -- 阻塞式等待获取锁 SELECT * FROM distributed_lock WHERE lock_key order_101 FOR UPDATE; -- 执行业务逻辑... COMMIT; -- 提交事务即释放锁⚠️ 致命注意点必须加索引在使用FOR UPDATE时WHERE后面的字段如lock_key必须有索引。有索引MySQL 使用行锁Row Lock只锁住这一行并发互不影响。无索引MySQL 无法定位行会进行全表扫描进而导致锁表。这会让系统的并发能力瞬间降为 1甚至导致数据库连接池爆满导致服务崩溃。优缺点分析优点理解简单不需要引入额外的中间件利用现有数据库。缺点性能差依赖磁盘 I/O并发支持有限。死锁风险基于 INSERT 的方案如果服务宕机锁无法自动释放需额外开发定时清理任务。连接资源宝贵基于FOR UPDATE的方案会长时间占用数据库连接。二、基于 Redis 实现分布式锁推荐这是目前互联网企业最常用的方案核心优势是高性能。1. 核心原理早期我们使用SETNX(Set if Not Exists) 指令但在生产环境中推荐使用Redisson框架它封装了复杂的底层逻辑。互斥利用 Redis 的原子操作同一时刻只有一个客户端能设置成功。防死锁设置过期时间TTL。自动续期看门狗 Watchdog这是 Redisson 的黑科技。如果业务逻辑执行时间超过了锁的过期时间看门狗会起一个后台线程每隔一段时间自动给锁“续命”防止业务没跑完锁就过期了。2. Java 代码示例 (Redisson)Autowired private RedissonClient redisson; public void doBusiness() { RLock lock redisson.getLock(my-lock); try { // 尝试加锁支持自动续期 lock.lock(); // 执行业务... System.out.println(Processing...); } finally { // 释放锁前判断是否是当前线程持有 if (lock.isLocked() lock.isHeldByCurrentThread()) { lock.unlock(); } } }优缺点分析优点性能极高纯内存操作实现简单Redisson 封装极其完善支持可重入。缺点AP 模型弱一致性。在 Redis 哨兵或集群模式下如果主节点还没来得及把锁同步给从节点就挂了从节点升级为主节点后锁会丢失可能导致两个线程同时持锁。三、基于 ZooKeeper 实现分布式锁ZooKeeper (ZK) 保证 CP强一致性适用于对可靠性要求极高的场景如金融核心系统。通常配合Curator客户端使用。1. 核心原理利用 ZK 的临时顺序节点 (Ephemeral Sequential Node)。抢锁所有客户端在/lock目录下创建一个临时顺序节点。判断获取所有子节点判断自己的序号是不是最小的。如果是获得锁。等待如果不是最小监听Watch比自己小 1 号的那个节点。释放前一个节点删除释放锁或宕机当前节点收到通知获得锁。优缺点分析优点强一致性不存在 Redis 的丢锁问题。安全性高因为是临时节点客户端宕机后节点自动消失天然杜绝死锁。缺点性能不如 Redis频繁创建和删除节点对 ZK 集群压力较大。四、总结与选型建议维度MySQLRedis (Redisson)ZooKeeper底层机制唯一索引 / 行锁SETNX / Lua 脚本临时顺序节点性能低 (磁盘I/O)极高 (内存)中 (网络/磁盘)一致性强 (依赖事务)弱 (主从切换可能丢锁)强 (CP模型)死锁风险高 (需兜底策略)低 (看门狗机制)无 (断开即释放)复杂度手动实现麻烦框架封装好框架封装好选型建议绝大多数互联网业务90%首选Redis (Redisson)。即使极端情况下偶尔丢锁通过业务层的幂等性校验也能兜底性能收益巨大。金融级/对一致性极其敏感的场景首选ZooKeeper。宁可慢一点也不能出差错。极小规模/不想引入新组件可以使用MySQL但务必记得给锁字段加唯一索引防止锁全表导致系统崩溃。作者提示技术选型没有绝对的“最好”只有“最适合”。在面试中回答此问题时建议先说出 Redis 的方案再对比 ZK 的强一致性优势最后提一下 MySQL 的实现原理及坑点展现你的知识广度。