Redis + Redisson 实现高可用分布式锁机制实战

在分布式系统中,多个节点对同一资源(如库存、订单、配置)进行并发操作时,如果没有同步机制,可能出现:

  • 超卖/重复扣减:多个线程同时修改库存,导致库存为负。

  • 重复任务执行:定时任务重复启动。

  • 数据冲突:并发写入数据库,造成数据异常。

为此,我们引入“分布式锁”机制,本文将以 Redisson 实现 Redis 分布式锁,实现高性能、高可靠的并发控制。


一、Redisson 简介

Redisson 是一个基于 Redis 的 Java 客户端框架,提供丰富的分布式对象支持:

  • 分布式锁(ReentrantLock、ReadWriteLock)

  • 分布式集合(Set、List、Map)

  • 延迟队列、布隆过滤器

  • 支持主从、哨兵、集群

相比原生 SETNX 方案,Redisson 封装了锁超时续约、WatchDog 机制、可重入等特性,更加安全和易用


二、引入依赖


xml

复制编辑

<dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.23.1</version> </dependency>


三、配置 Redis 连接


yaml

复制编辑

spring: redis: host: 127.0.0.1 port: 6379 redisson: singleServerConfig: address: redis://127.0.0.1:6379


四、Redisson 自动配置类(可选)


java

复制编辑

@Configuration public class RedissonConfig { @Bean public RedissonClient redissonClient() { Config config = new Config(); config.useSingleServer().setAddress("redis://127.0.0.1:6379"); return Redisson.create(config); } }

若使用 redisson-spring-boot-starter,可省略此配置。


五、实现分布式锁代码逻辑

以库存扣减为例:

mbb.eet-china.com/blog/4120085-468426.html

java

复制编辑

@Service public class StockService { @Autowired private RedissonClient redissonClient; // 模拟库存 private AtomicInteger stock = new AtomicInteger(10); public String deductStock(String productId) { String lockKey = "lock:stock:" + productId; RLock lock = redissonClient.getLock(lockKey); boolean isLocked = false; try { // 尝试加锁(最多等待3秒,锁自动释放时间10秒) isLocked = lock.tryLock(3, 10, TimeUnit.SECONDS); if (isLocked) { if (stock.get() > 0) { stock.decrementAndGet(); return "扣减成功,剩余:" + stock.get(); } else { return "库存不足"; } } else { return "系统繁忙,请稍后重试"; } } catch (InterruptedException e) { Thread.currentThread().interrupt(); return "加锁失败"; } finally { if (isLocked && lock.isHeldByCurrentThread()) { lock.unlock(); // 释放锁 } } } }


六、控制器测试接口

bbs.gongkong.com/d/202507/941307/941307_1.shtml

java

复制编辑

@RestController @RequestMapping("/api/stock") public class StockController { @Autowired private StockService stockService; @GetMapping("/deduct") public String deduct(@RequestParam String productId) { return stockService.deductStock(productId); } }

你可以使用压测工具(如 JMeter、Postman)模拟并发请求。


七、常见使用方式

使用方式示例代码
获取锁(自动续期)lock.lock();
可重入锁同一线程可重复获取
读写锁getReadWriteLock().readLock().lock();
公平锁(FIFO)getFairLock()
尝试锁(带超时等待)tryLock(5, 10, TimeUnit.SECONDS)
自动释放锁(无需 unlock)lock.lock(10, TimeUnit.SECONDS);

bbs.eeworld.com.cn/thread-1320007-1-1.html


八、避免死锁的机制:WatchDog

当你使用:

club.mscbsc.com/t731572p1.html

java

复制编辑

lock.lock(); // 不传超时时间

Redisson 会启动 WatchDog 看门狗机制

  • 默认锁有效期为 30 秒

  • 若线程未释放,WatchDog 每 10 秒自动续约

  • 避免因业务执行时间过长导致锁提前释放

若使用 lock.lock(10, TimeUnit.SECONDS),将不会启动看门狗机制,锁在 10 秒后自动释放。


九、分布式锁常见应用场景

场景描述
库存扣减多线程/多节点下防止超卖
秒杀系统抢购入口防刷,商品扣减互斥
订单防重复提交同一个用户提交按钮多次点击
定时任务单点执行保证同一任务不被多个节点同时执行
防止缓存击穿高并发时热点 Key 加锁处理

scarbbs.com/thread-527191-1-1.html


十、分布式锁与本地锁的对比

特性本地锁(synchronized / ReentrantLockRedis 分布式锁
跨节点有效
自动超时释放❌(异常可能死锁)✅(支持 WatchDog)
可重入
性能高(进程内)稍低(网络 + Redis 开销)
场景单机并发控制分布式场景必选

blog.itpub.net/70045253/viewspace-3089609


十一、注意事项与最佳实践

建议说明
使用 tryLock 而非 lock避免死锁风险,添加超时时间
锁粒度控制锁 Key 要细化,如 lock:stock:sku123
锁释放前判断线程身份lock.isHeldByCurrentThread() 保护性释放
避免长时间持有锁拆分逻辑或异步处理,提升系统并发能力
多操作需封装事务内若涉及数据库更新,考虑放入事务中

mbb.eet-china.com/blog/4120314-468425.html
blog.51cto.com/u_17434514/14029866


十二、总结

本文完整实现了基于 Redisson 的分布式锁机制

  • Redisson 配置与连接 Redis

  • 使用 RLock 实现锁获取与释放

  • 封装库存扣减案例

  • 支持自动续期、超时释放等能力

  • 介绍了 WatchDog、可重入、公平锁等功能

分布式锁是微服务系统中控制并发冲突的基础能力,Redisson 提供了一套完备、安全、高性能的实现方案,推荐在业务开发中优先使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值