Redisson分布式锁:从入门到实战
一、为什么需要分布式锁在单体应用中我们使用Java的synchronized或ReentrantLock就能解决并发问题。但在微服务架构下多个实例同时运行单机的锁机制就失效了。这时就需要分布式锁来保证跨JVM的互斥访问。分布式锁的核心需求互斥性同一时刻只能有一个客户端持有锁防止死锁客户端崩溃后能自动释放锁容错性Redis节点故障时仍能正常工作可重入性同一个线程可以多次获取同一个锁二、Redis实现分布式锁的基础方案2.1 最简单的实现SET NX最早期的实现方式是使用SET命令的NX选项SET key value NX PX 30000NX只在key不存在时设置PX设置过期时间毫秒这种方式的缺点无法实现可重入锁无法获取锁的持有人信息无法实现锁的自动续期2.2 完整实现方案一个相对完善的Redis分布式锁实现需要包含以下逻辑Redis分布式锁基础架构加锁SET key value NX PX timeout解锁Lua脚本保证原子性看门狗定时续期防止业务执行时间超过锁过期时间三、Redisson分布式锁Redisson是Redis的Java客户端它提供了完善的分布式锁实现解决了原生Redis锁的各种问题。3.1 核心特性可重入锁同一个线程可多次获取锁公平锁按请求顺序获取锁读写锁允许多个读操作或单个写操作红锁跨多个Redis节点的分布式锁自动续期看门狗机制自动延长锁时间锁释放Lua脚本保证原子性操作3.2 基本使用// 获取锁对象 RLock lock redisson.getLock(myLock); try { // 加锁支持等待时间和自动续期 boolean locked lock.tryLock(100, 30000, TimeUnit.MILLISECONDS); if (locked) { // 执行业务逻辑 doBusiness(); } } finally { // 释放锁 if (lock.isHeldByCurrentThread()) { lock.unlock(); } }四、Redis实现 vs Redisson对比Redis实现 vs Redisson对比特性Redis原生实现Redisson实现复杂度高需要处理多种边界情况低开箱即用可重入锁需要自己实现原生支持自动续期需要后台线程续期看门狗自动续期公平锁难以实现开箱即用读写锁难以实现开箱即用红锁需要自己协调开箱即用异常处理需要仔细处理完善的异常体系结论生产环境推荐使用Redisson它已经处理了各种边界情况和异常场景。五、Redisson核心原理解析5.1 加锁机制Redisson使用Lua脚本保证加锁的原子性Redisson加解锁流程-- 检查key是否存在 if redis.call(exists, KEYS[1]) 0 then -- 不存在则设置使用hash结构存储 redis.call(hset, KEYS[1], ARGV[2], 1) redis.call(pexpire, KEYS[1], ARGV[1]) return nil end -- key已存在检查是否是当前线程 if redis.call(hexists, KEYS[1], ARGV[2]) 1 then -- 是当前线程增加重入次数 redis.call(hincrby, KEYS[1], ARGV[2], 1) redis.call(pexpire, KEYS[1], ARGV[1]) return nil end return redis.call(pttl, KEYS[1])锁的数据结构使用Hash类型Key锁名称Field线程标识UUID:threadIdValue重入次数5.2 看门狗机制看门狗Watchdog是Redisson的核心特性用于解决锁超时问题Watchdog机制业务获得锁时启动后台定时任务每隔lockWatchdogTimeout/3时间检查锁是否还持有如果还持有则重置过期时间业务释放锁时停止看门狗默认情况下看门狗每10秒续期一次锁的过期时间为30秒。5.3 解锁机制解锁同样使用Lua脚本保证原子性-- 检查锁是否是当前线程持有 if redis.call(hexists, KEYS[1], ARGV[2]) 0 then return nil end -- 减少重入次数 local counter redis.call(hincrby, KEYS[1], ARGV[2], -1) -- 如果重入次数大于0重置过期时间 if counter 0 then redis.call(pexpire, KEYS[1], ARGV[1]) return 0 end -- 重入次数为0删除锁 redis.call(del, KEYS[1]) -- 发布解锁消息 redis.call(publish, KEYS[2], ARGV[3]) return 1六、生产环境实战案例生产环境实战案例6.1 库存扣减Service public class InventoryService { Autowired private RedissonClient redisson; public boolean deductStock(String productId, int quantity) { RLock lock redisson.getLock(stock: productId); try { // 等待5秒锁过期30秒 if (lock.tryLock(5, 30, TimeUnit.SECONDS)) { // 查询库存 int stock getStock(productId); if (stock quantity) { // 扣减库存 updateStock(productId, stock - quantity); return true; } return false; } throw new BusinessException(系统繁忙请稍后重试); } finally { if (lock.isHeldByCurrentThread()) { lock.unlock(); } } } }6.2 订单幂等性控制Service public class OrderService { Autowired private RedissonClient redisson; public Order createOrder(OrderRequest request) { String lockKey order:create: request.getUserId(); RLock lock redisson.getLock(lockKey); try { if (lock.tryLock(3, 10, TimeUnit.SECONDS)) { // 检查是否已有未完成订单 Order existOrder getUnfinishedOrder(request.getUserId()); if (existOrder ! null) { return existOrder; } // 创建新订单 Order order buildOrder(request); saveOrder(order); return order; } throw new BusinessException(操作频繁请稍后重试); } finally { if (lock.isHeldByCurrentThread()) { lock.unlock(); } } } }6.3 定时任务防止重复执行Component public class DataSyncJob { Autowired private RedissonClient redisson; Scheduled(cron 0 */5 * * * *) public void syncData() { String lockKey job:data:sync; RLock lock redisson.getLock(lockKey); try { // 尝试获取锁不等待 if (lock.tryLock(0, TimeUnit.SECONDS)) { // 执行数据同步 doSync(); } else { log.info(上次同步任务尚未完成跳过本次执行); } } finally { if (lock.isHeldByCurrentThread()) { lock.unlock(); } } } }七、高级特性读写锁在读多写少的场景下使用读写锁可以大幅提升并发性能读写锁原理Service public class ConfigService { Autowired private RedissonClient redisson; public String getConfig(String key) { RReadWriteLock rwLock redisson.getReadWriteLock(config: key); RLock readLock rwLock.readLock(); try { readLock.lock(); // 多个线程可以同时读取 return queryFromDB(key); } finally { readLock.unlock(); } } public void updateConfig(String key, String value) { RReadWriteLock rwLock redisson.getReadWriteLock(config: key); RLock writeLock rwLock.writeLock(); try { // 写操作独占锁 writeLock.lock(); updateDB(key, value); // 清除缓存 clearCache(key); } finally { writeLock.unlock(); } } }八、最佳实践8.1 锁的粒度选择粗粒度锁整个表或模块简单但并发度低细粒度锁单个记录并发度高但实现复杂推荐根据业务场景选择合适的粒度库存扣减用商品维度订单创建用用户维度。8.2 锁的过期时间设置不要设置过短避免业务未执行完就释放不要设置过长避免故障时长时间阻塞Redisson的看门狗会自动续期但要设置合理的初始时间推荐根据业务执行时间的P99值设置预留50%余量。8.3 异常处理捕获中断异常确保锁能被释放使用tryLock而不是lock避免无限等待检查锁的持有状态避免误释放九、常见问题Q1Redisson锁会丢失吗不会。Redisson使用看门狗机制即使业务执行时间超过锁的过期时间也会自动续期直到业务主动释放锁。Q2Redis主从切换会影响锁吗会。单节点Redis在主从切换时可能丢失锁。需要使用Redisson的红锁RedLock或Redis Cluster。Q3如何实现公平锁Redisson提供了公平锁实现RLock fairLock redisson.getFairLock(myFairLock); fairLock.lock();Q4性能如何Redisson的分布式锁性能很好单机QPS可达5万足以应对大多数场景。如有更高性能需求可以考虑分段锁或本地锁分布式锁的组合方案。十、总结Redisson分布式锁是Java领域最成熟的Redis分布式锁解决方案使用简单API友好学习成本低功能完善支持多种锁类型和场景稳定可靠经过大量生产环境验证性能优异看门狗机制和Lua脚本保证性能在实际项目中建议优先使用Redisson它已经帮你处理了各种复杂的边界情况让你专注于业务逻辑的实现。

相关新闻

Web自动化测试教程

Web自动化测试教程

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、自动化测试基本介绍1、自动化测试概述:什么是自动化测试?一般说来所有能替代人工测试的方式都属于自动化测试,即通过工具和…

2026/7/3 15:41:37 阅读更多 →
【电赛】电赛报告注意事项

【电赛】电赛报告注意事项

设计报告

2026/7/3 15:41:44 阅读更多 →
【Linux】—— FTP服务搭建与使用(Ubuntu实操版,适配办公内网)

【Linux】—— FTP服务搭建与使用(Ubuntu实操版,适配办公内网)

【Linux】—— FTP服务搭建与使用(Ubuntu实操版,适配办公内网) 在办公场景中,经常需要实现Windows与Linux(Ubuntu)之间的文件传输,FTP服务因其稳定性、兼容性,成为内网文件共享的首…

2026/7/3 15:41:43 阅读更多 →

最新新闻

拯救者笔记本性能优化终极手册:Lenovo Legion Toolkit完全指南

拯救者笔记本性能优化终极手册:Lenovo Legion Toolkit完全指南

拯救者笔记本性能优化终极手册:Lenovo Legion Toolkit完全指南 【免费下载链接】LenovoLegionToolkit Lightweight Lenovo Vantage and Hotkeys replacement for Lenovo Legion laptops. 项目地址: https://gitcode.com/gh_mirrors/le/LenovoLegionToolkit 你…

2026/7/4 0:52:47 阅读更多 →
化学机器学习实战:分子表征、反应预测与量子化学加速

化学机器学习实战:分子表征、反应预测与量子化学加速

1. 这不是“AI写论文”的噱头,而是化学家手边正在变快的实验加速器“Machine Learning in Chemistry”——这个标题听起来像学术会议上的一个分论坛名称,但如果你最近翻过《Nature Chemistry》《Journal of Chemical Information and Modeling》或者ACS旗…

2026/7/4 0:52:47 阅读更多 →
单调栈题解:栈里存的不是元素,是还没等到答案的位置

单调栈题解:栈里存的不是元素,是还没等到答案的位置

单调栈题解:栈里存的不是元素,是还没等到答案的位置 单调栈是高频题,但很多人背模板背得很痛苦。其实单调栈的核心很简单:栈里存的不是普通元素,而是“还没等到答案的位置”。每来一个新元素,就看看它能不能…

2026/7/4 0:50:47 阅读更多 →
MinIO Windows部署与Java集成实战:从安装避坑到SDK源码级调优

MinIO Windows部署与Java集成实战:从安装避坑到SDK源码级调优

1. 这不是又一个“Hello World”式对象存储教程——MinIO 真正该被理解的起点MinIO 不是另一个需要你花三天配环境、两天调依赖、最后只跑通一个上传接口的玩具项目。它是一套在生产环境里扛住每秒数万次 PUT/GET 请求、支撑 PB 级非结构化数据冷热分层、被全球数千家银行、保险…

2026/7/4 0:50:47 阅读更多 →
如何快速上手智能缠论分析:ChanlunX股票技术分析终极指南

如何快速上手智能缠论分析:ChanlunX股票技术分析终极指南

如何快速上手智能缠论分析:ChanlunX股票技术分析终极指南 【免费下载链接】ChanlunX 缠中说禅炒股缠论可视化插件 项目地址: https://gitcode.com/gh_mirrors/ch/ChanlunX ChanlunX缠论可视化插件是一款专为通达信用户设计的智能股票分析工具,能够…

2026/7/4 0:46:46 阅读更多 →
KMR221与PIC18F86J15的嵌入式电压管理方案

KMR221与PIC18F86J15的嵌入式电压管理方案

1. 项目概述:KMR221与PIC18F86J15的电压管理方案在嵌入式系统设计中,精确的电压管理一直是硬件工程师面临的挑战。最近我在一个工业控制项目中,尝试将KMR221电源管理IC与PIC18F86J15微控制器结合使用,实现了令人满意的电压控制效果…

2026/7/4 0:42:44 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻