当前位置: 首页 > article >正文

从零到一:深入浅出分布式锁原理与Spring Boot实战(Redis + ZooKeeper)

一、为什么需要分布式锁——从单机到分布式的必然选择1.1 单机锁的局限性在传统单体架构中我们习惯使用synchronized、ReentrantLock等同步机制来控制并发访问。但这些锁机制存在致命缺陷仅限于单 JVM只能锁住同一个 Java 虚拟机内的线程无法跨进程当服务部署在多台服务器上时每台机器都有独立的锁实例无法跨网络不同服务实例之间无法感知彼此的锁状态1.2 真实业务场景的痛点电商秒杀场景库存只有 10 件商品但成千上万的用户同时下单。在分布式部署架构下服务 A 实例扣减库存到 5 件服务 B 实例同时读取库存还是 10 件也扣减到 5 件最终库存变成 0但实际只卖出了 10 件却扣减了 20 件库存支付对账场景多个对账任务同时执行都需要更新对账状态表如果没有分布式锁可能导致状态错乱。1.3 分布式锁的核心价值跨进程互斥保证同一时刻只有一个客户端能执行关键代码数据一致性避免多个服务实例同时修改共享资源导致的数据不一致业务可靠性确保关键业务逻辑的原子性和完整性二、分布式锁的六大必备条件——生产环境的底线要求一个真正可用的分布式锁必须满足以下核心条件条件说明重要性互斥性任意时刻只有一个客户端能持有锁⭐⭐⭐⭐⭐防死锁锁持有者崩溃时锁能自动释放如设置超时时间⭐⭐⭐⭐⭐容错性锁服务本身高可用部分节点故障不影响整体功能⭐⭐⭐⭐可重入性同一线程可重复获取已持有的锁避免自己阻塞自己⭐⭐⭐高性能加锁、解锁操作要快延迟低避免成为系统瓶颈⭐⭐⭐⭐公平性按照请求顺序获取锁避免饥饿现象可选但重要⭐⭐⭐重点强调在生产环境中互斥性和防死锁是绝对不能妥协的底线要求三、分布式锁的常见实现方案——技术选型指南3.1 主流方案对比实现方式核心原理优点缺点适用场景数据库乐观锁版本号或唯一键约束简单无需额外组件性能差易死锁不适合高并发低并发、快速验证场景 Redis 方案 SETNX 过期时间 Lua 脚本高性能实现简单生态成熟依赖时钟主从切换可能丢锁高并发、允许极少量不一致的场景 ZooKeeper 方案临时顺序节点 Watch 机制强一致性无死锁风险天然公平性能相对较低运维成本高金融级、强一致性要求场景 Etcd 方案 Raft 共识 Lease Revision 强一致云原生友好生态相对小众 Kubernetes实现方式核心原理优点缺点适用场景数据库乐观锁版本号或唯一键约束简单无需额外组件性能差易死锁不适合高并发低并发、快速验证场景Redis方案SETNX 过期时间 Lua脚本高性能实现简单生态成熟依赖时钟主从切换可能丢锁高并发、允许极少量不一致的场景ZooKeeper方案临时顺序节点 Watch机制强一致性无死锁风险天然公平性能相对较低运维成本高金融级、强一致性要求场景Etcd方案Raft共识 Lease Revision强一致云原生友好生态相对小众Kubernetes环境、云原生架构环境、云原生架构3.2 方案选型建议首选 Redis90% 的业务场景特别是高并发、低延迟要求的场景金融级场景选 ZooKeeper/Etcd对数据一致性要求极高的场景如资金转账、库存扣减避免自研除非有特殊需求否则优先使用成熟框架如 Redisson、Curator四、Redis 分布式锁实战——高性能方案详解4.1 核心原理深度剖析基础命令SET lock_key unique_value NX PX 30000NXOnly set the key if it does not already exist保证互斥PXSet the expiration time in milliseconds防死锁unique_valueUUID 等唯一标识安全释放锁释放锁的原子性问题-- Lua 脚本保证原子性 if Redis.call(「get」, KEYS[1]) ARGV[1] then return Redis.call(「del」, KEYS[1]) else return 0 end为什么要用 Lua 脚本因为”判断 value 是否匹配”和”删除 key”是两个操作如果不原子执行可能出现客户端 A 判断 value 匹配锁恰好过期客户端 B 获取到新锁客户端 A 删除了客户端 B 的锁4.2 Spring Boot 完整实现生产级4.2.1 基础依赖配置dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-Redis/artifactId /dependency dependency groupIdorg.redisson/groupId artifactIdredisson-spring-boot-starter/artifactId version3.27.0/version /dependency4.2.2 Redisson 配置Configuration public class RedissonConfig { Value(「${spring.Redis.host}」) private String redisHost; Value(「${spring.Redis.port}」) private int redisPort; Bean(destroyMethod 「shutdown」) public RedissonClient redissonClient() { Config config new Config(); config.useSingleServer() .setAddress(「Redis://」 redisHost 「:」 redisPort) .setConnectionPoolSize(10) .setConnectionMinimumIdleSize(5) .setRetryAttempts(3) .setRetryInterval(1000); return Redisson.create(config); } }4.2.3 业务代码示例Service public class OrderService { Autowired private RedissonClient redissonClient; Autowired private InventoryService inventoryService; /** * 创建订单带分布式锁 * / public Order createOrder(String userId, String productId, int quantity) { // 锁 key订单创建锁 产品 ID String lockKey 「order:create:」 productId; // 获取锁看门狗自动续期 RLock lock redissonClient.getLock(lockKey); try { // 尝试获取锁最多等待 10 秒锁自动释放时间 30 秒 boolean locked lock.tryLock(10, 30, TimeUnit.SECONDS); if (!locked) { throw new BusinessException(「系统繁忙请稍后重试」); } // 检查库存 if (!inventoryService.checkStock(productId, quantity)) { throw new BusinessException(「库存不足」); } // 扣减库存并创建订单 inventoryService.deductStock(productId, quantity); return orderRepository.save(new Order(userId, productId, quantity)); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new BusinessException(「获取锁被中断」); } finally { // 释放锁 if (lock.isLocked() lock.isHeldByCurrentThread()) { lock.unlock(); } } } }4.3 Redisson 实现原理揭秘看门狗Watchdog机制当锁未指定 leaseTimeout 时默认 30 秒过期后台启动定时任务每 10 秒检查一次如果客户端仍持有锁自动重置过期时间为 30 秒业务完成后手动释放锁取消看门狗优势无需手动设置过期时间避免业务执行时间过长导致锁提前释放自动续期保证业务完整性五、ZooKeeper 分布式锁实战——强一致性方案5.1 核心原理深度解析ZooKeeper 节点类型持久节点客户端断开后依然存在临时节点客户端会话结束自动删除关键顺序节点父节点下自动生成递增序号加锁流程公平锁所有客户端在/locks/order下创建临时顺序节点获取所有子节点判断自己创建的节点序号是否最小如果是最小获取锁成功如果不是最小监听前一个序号节点的删除事件前一个节点删除后重新判断释放锁删除临时节点或会话断开自动删除优势强一致性ZAB 协议保证数据一致性无死锁临时节点自动释放天然公平按创建顺序获取锁5.2 Spring Boot 完整实现Curator 框架5.2.1 依赖配置dependency groupIdorg.apache.curator/groupId artifactIdcurator-recipes/artifactId version5.5.0/version /dependency dependency groupIdorg.apache.curator/groupId artifactIdcurator-framework/artifactId version5.5.0/version /dependency5.2.2 Curator 客户端配置Configuration public class ZookeeperConfig { Value(「${zookeeper.address}」) private String zkAddress; Value(「${zookeeper.sessionTimeout}」) private int sessionTimeout 30000; Value(「${zookeeper.connectionTimeout}」) private int connectionTimeout 15000; Bean(initMethod 「start」, destroyMethod 「close」) public CuratorFramework curatorFramework() { // 重试策略指数退避初始 1 秒最多 3 次 RetryPolicy retryPolicy new ExponentialBackoffRetry(1000, 3); return CuratorFrameworkFactory.builder() .connectString(zkAddress) .sessionTimeoutMs(sessionTimeout) .connectionTimeoutMs(connectionTimeout) .retryPolicy(retryPolicy) .build(); } }5.2.3 业务代码示例Service public class PaymentService { Autowired private CuratorFramework curatorFramework; Autowired private AccountService accountService; /** * 转账操作强一致性要求 * / public boolean transfer(String fromAccount, String toAccount, BigDecimal amount) { // 锁路径/locks/transfer/{fromAccount} String lockPath 「/locks/transfer/」 fromAccount; InterProcessMutex lock new InterProcessMutex(curatorFramework, lockPath); try { // 尝试获取锁最多等待 15 秒 if (!lock.acquire(15, TimeUnit.SECONDS)) { throw new BusinessException(「获取锁超时请稍后重试」); } // 检查余额 BigDecimal balance accountService.getBalance(fromAccount); if (balance.compareTo(amount) 0) { throw new BusinessException(「余额不足」); } // 执行转账强一致性要求 accountService.deduct(fromAccount, amount); accountService.add(toAccount, amount); return true; } catch (Exception e) { log.error(「转账失败」, e); throw new BusinessException(「转账失败」 e.getMessage()); } finally { try { // 释放锁 if (lock.isAcquiredInThisProcess()) { lock.release(); } } catch (Exception e) { log.error(「释放锁失败」, e); } } } }5.3 ZooKeeper vs Redis 深度对比维度 ZooKeeperRedis 一致性强一致性ZAB 协议最终一致性主从异步性能较低涉及磁盘写入极高内存操作可靠性无单点风险自动故障转移依赖哨兵/集群主从切换可能丢锁实现复杂度较高需要维护 ZK 集群较低Redis维度ZooKeeperRedis一致性强一致性ZAB协议最终一致性主从异步性能较低涉及磁盘写入极高内存操作可靠性无单点风险自动故障转移依赖哨兵/集群主从切换可能丢锁实现复杂度较高需要维护ZK集群较低Redis部署简单适用场景金融级、强一致性要求高并发、允许极少量不一致部署简单适用场景金融级、强一致性要求高并发、允许极少量不一致六、生产环境最佳实践——避坑指南6.1 Redis 方案注意事项避免锁过期问题业务执行时间可能超过锁过期时间使用 Redisson 看门狗自动续期业务拆分避免长事务主从切换风险单机 Redis 哨兵架构足够应对大多数场景极端重要场景考虑 Redlock 算法争议较大性能优化使用连接池合理设置超时时间避免在锁内执行 IO 操作6.2 ZooKeeper 方案注意事项会话超时设置合理配置 sessionTimeout避免网络抖动导致频繁释放锁一般设置为 30-60 秒连接管理使用连接池处理连接断开重连监控 ZK 集群状态节点路径设计避免创建过多节点合理设计节点层级定期清理无用节点6.3 通用最佳实践锁粒度尽量细粒度锁避免大范围锁竞争超时机制必须设置获取锁的超时时间避免无限等待异常处理完善的异常处理和日志记录监控告警监控锁的获取时间、持有时间、失败率降级策略当锁服务不可用时有降级方案七、总结与选型决策树7.1 技术选型决策树7.2 核心结论90% 场景选 Redis性能高、实现简单、生态成熟10% 关键场景选 ZooKeeper强一致性、无死锁风险、金融级要求永远不要自研除非有特殊需求否则优先使用成熟框架锁是最后手段优先考虑无锁化设计如分库分表、消息队列

相关文章:

从零到一:深入浅出分布式锁原理与Spring Boot实战(Redis + ZooKeeper)

一、为什么需要分布式锁?——从单机到分布式的必然选择1.1 单机锁的局限性在传统单体架构中,我们习惯使用 synchronized、ReentrantLock 等同步机制来控制并发访问。但这些锁机制存在致命缺陷:仅限于单 JVM:只能锁住同一个 Java 虚…...

八大网盘直链下载终极解决方案:LinkSwift完整指南

八大网盘直链下载终极解决方案:LinkSwift完整指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘…...

NVIDIA GPU学习复盘2-半精度、单精度与双精度运算

理解数据类型和大小,就像在工具箱中选择合适的工具一样。1、整数(integer):使用8 16 32 64位,位数越多,存储的数值就越大。例如:8位整数在无符号情况下可以存储0-255之间的值;有符号…...

从相关到因果:一文读懂因果Transformer的核心与应用

从相关到因果:一文读懂因果Transformer的核心与应用 引言:AI的下一站——因果推理 当前,以Transformer为代表的大模型在捕捉数据相关性上取得了巨大成功,从GPT系列到各类视觉大模型,无不展示了其强大的模式识别能力。…...

乙巳马年春联生成终端惊艳效果:生成结果嵌入NFT合约的区块链版权存证演示

乙巳马年春联生成终端惊艳效果:生成结果嵌入NFT合约的区块链版权存证演示 1. 引言:当传统春联遇见前沿科技 春节贴春联,是传承千年的文化习俗。一副好春联,不仅寄托着人们对新年的美好祝愿,更是一件凝聚了智慧与美感…...

黑苹果终极实战指南:OpenCore长期维护机型EFI深度解密

黑苹果终极实战指南:OpenCore长期维护机型EFI深度解密 【免费下载链接】Hackintosh Hackintosh long-term maintenance model EFI and installation tutorial 项目地址: https://gitcode.com/gh_mirrors/ha/Hackintosh 还在为苹果电脑的高昂价格望而却步&…...

别再乱调了!3ds Max里Gamma 2.2和LUT到底怎么设?一份给材质渲染与后期合成的设置指南

3ds Max色彩管理终极指南:Gamma 2.2与LUT设置全解析 当你在3ds Max中完成一个精美的材质渲染,却发现最终输出到合成软件时颜色完全不对——这种崩溃感每个3D艺术家都经历过。问题的根源往往在于色彩管理流程中的Gamma和LUT设置不当。本文将带你深入理解这…...

Docker Compose实战指南

本文基于 Docker Compose V2,所有内容均来自 Docker 官方文档和生产环境实践。全文约 14800 字,建议收藏后阅读。读完本文,你将从 Docker Compose 新手成长为能够独立部署复杂多容器应用的专家。一、Docker Compose 核心概念与底层原理1.1 什…...

2026届必备的十大降AI率方案推荐

Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 对于学术写作以及内容创作而言,要降低AI生成内容能够被识别出来的概率&#xff0…...

手把手教你为STM32移植AK09918磁力计驱动(附Linux驱动对比与源码)

从零构建STM32磁力计驱动:AK09918移植实战与Linux对比 在无人机飞控和智能穿戴设备开发中,地磁传感器是实现方向感知的核心部件。AKM公司的AK09918作为三轴磁力计中的佼佼者,以其高精度和低功耗特性受到嵌入式开发者的青睐。但将这颗传感器成…...

STM32CubeMX LL库串口通信避坑指南:从配置到中断处理的完整流程(基于STM32F103)

STM32CubeMX LL库串口通信避坑指南:从配置到中断处理的完整流程(基于STM32F103) 当你第一次用STM32CubeMX生成LL库串口通信代码时,是否遇到过这样的场景:代码编译一切正常,下载到板子后却发现串口死活不工作…...

告别MCU直连U盘的烦恼:用CH376模块为你的Arduino/ESP32项目轻松扩展USB存储

告别MCU直连U盘的烦恼:用CH376模块为你的Arduino/ESP32项目轻松扩展USB存储 你是否遇到过这样的场景:精心设计的Arduino环境监测站运行了一周,采集了上千组温湿度数据,却因为缺乏本地存储功能而被迫丢弃?或是ESP32摄像…...

SystemVerilog里用disable fork,为啥总把隔壁进程也“误杀”了?

SystemVerilog中disable fork的"误杀"陷阱与精准控制策略 在芯片验证和FPGA开发领域,SystemVerilog的并发进程管理是构建高效测试平台的核心技能之一。许多工程师在使用disable fork时都遭遇过这样的困境:明明只想终止某个特定分支的进程&…...

如何通过Universal Android Debloater实现手机性能翻倍?终极指南揭秘

如何通过Universal Android Debloater实现手机性能翻倍?终极指南揭秘 【免费下载链接】universal-android-debloater Cross-platform GUI written in Rust using ADB to debloat non-rooted android devices. Improve your privacy, the security and battery life …...

从内存泄漏到数据错乱:调试Linux共享内存(shm)程序的3个常见坑与解决方案

从内存泄漏到数据错乱:调试Linux共享内存(shm)程序的3个常见坑与解决方案 在分布式系统和高性能计算领域,共享内存(Shared Memory)作为进程间通信(IPC)的最高效方式之一,被广泛应用于需要低延迟…...

BilibiliDown:三分钟学会下载B站视频的跨平台神器

BilibiliDown:三分钟学会下载B站视频的跨平台神器 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors/bi/Bi…...

OBS Advanced Timer终极指南:6种专业计时模式快速上手

OBS Advanced Timer终极指南:6种专业计时模式快速上手 【免费下载链接】obs-advanced-timer 项目地址: https://gitcode.com/gh_mirrors/ob/obs-advanced-timer OBS Advanced Timer是一款功能强大的OBS计时器插件,专门为直播主和内容创作者设计&…...

WarcraftHelper深度解析:专业级魔兽争霸III兼容性与性能优化方案

WarcraftHelper深度解析:专业级魔兽争霸III兼容性与性能优化方案 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 魔兽争霸III作为经典的即…...

Qt Creator项目里集成工业相机SDK,手把手教你配置.pro文件(附避坑点)

Qt Creator工业相机SDK集成实战:从配置到团队协作的最佳实践 工业视觉系统的开发往往需要将硬件厂商提供的相机SDK与Qt框架深度整合。不同于普通的第三方库集成,工业相机SDK通常涉及复杂的设备通信、图像采集和内存管理机制。本文将分享在Qt Creator中高…...

ITK-SNAP医学图像分割:当传统算法遇上现代交互的深度技术融合

ITK-SNAP医学图像分割:当传统算法遇上现代交互的深度技术融合 【免费下载链接】itksnap ITK-SNAP medical image segmentation tool 项目地址: https://gitcode.com/gh_mirrors/it/itksnap 你是否曾面对复杂的医学影像数据,在手动标注的耗时与自动…...

如何在Windows上获得原生级苹果触控板体验:mac-precision-touchpad完整指南

如何在Windows上获得原生级苹果触控板体验:mac-precision-touchpad完整指南 【免费下载链接】mac-precision-touchpad Windows Precision Touchpad Driver Implementation for Apple MacBook / Magic Trackpad 项目地址: https://gitcode.com/gh_mirrors/ma/mac-p…...

3分钟掌握浏览器音高检测:PitchDetect让音乐分析触手可及

3分钟掌握浏览器音高检测:PitchDetect让音乐分析触手可及 【免费下载链接】PitchDetect Pitch detection in Web Audio using autocorrelation 项目地址: https://gitcode.com/gh_mirrors/pi/PitchDetect 在音乐学习、乐器调音或音频分析中,实时获…...

FanControl传感器异常终极解决方案:三步诊断与高效修复指南

FanControl传感器异常终极解决方案:三步诊断与高效修复指南 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trendi…...

避坑指南:解决Docker运行ROS时Gazebo/Rviz黑屏或无法显示的5个关键配置

避坑指南:解决Docker运行ROS时Gazebo/Rviz黑屏或无法显示的5个关键配置 当你在Docker容器中运行ROS时,最令人沮丧的莫过于Gazebo或Rviz窗口无法正常显示。这就像准备了一场精彩的机器人演示,却发现观众席一片漆黑。本文将深入剖析这个常见问…...

如何快速自动化获取和安装Boot Camp驱动:Brigadier终极指南

如何快速自动化获取和安装Boot Camp驱动:Brigadier终极指南 【免费下载链接】brigadier Fetch and install Boot Camp ESDs with ease. 项目地址: https://gitcode.com/gh_mirrors/bri/brigadier Brigadier是一款跨平台智能驱动管理工具,专为Mac设…...

Android虚拟摄像头终极配置指南:5分钟实现视频替换与隐私保护

Android虚拟摄像头终极配置指南:5分钟实现视频替换与隐私保护 【免费下载链接】com.example.vcam 虚拟摄像头 virtual camera 项目地址: https://gitcode.com/gh_mirrors/co/com.example.vcam 还在为直播画面单调而烦恼?想要保护隐私又需要摄像头…...

如何突破Windows应用程序的尺寸限制?WindowResizer的底层技术解析与应用实践

如何突破Windows应用程序的尺寸限制?WindowResizer的底层技术解析与应用实践 【免费下载链接】WindowResizer 一个可以强制调整应用程序窗口大小的工具 项目地址: https://gitcode.com/gh_mirrors/wi/WindowResizer 在Windows生态系统中,应用程序…...

如何高效解锁二手iPhone?applera1n智能激活锁绕过方案深度解析

如何高效解锁二手iPhone?applera1n智能激活锁绕过方案深度解析 【免费下载链接】applera1n icloud bypass for ios 15-16 项目地址: https://gitcode.com/gh_mirrors/ap/applera1n 当您满怀期待地打开新购买的二手iPhone,却遭遇"激活锁"…...

角色设计效率翻倍:Nunchaku FLUX.1 CustomV3实战,快速迭代不同发型与肤质的角色原型

角色设计效率翻倍:Nunchaku FLUX.1 CustomV3实战,快速迭代不同发型与肤质的角色原型 1. 为什么角色设计师需要关注Nunchaku FLUX.1 CustomV3? 在角色设计领域,我们经常面临一个核心挑战:如何在有限时间内快速验证不同…...

CLAP音频分类降本提效:相比微调方案节省90%标注与训练成本

CLAP音频分类降本提效:相比微调方案节省90%标注与训练成本 1. 音频分类的新选择 传统音频分类需要大量标注数据和长时间训练,现在有了更简单的方法。CLAP音频分类技术让你不用标注一张标签,不用训练一分钟模型,就能完成专业级的…...