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

从零理解 Redisson:Java 分布式工具箱的入门与实战

从零理解 Redisson:Java 分布式工具箱的入门与实战

一、Redisson 是什么

1.1 一句话定义

Redisson 是一个基于 Redis 的 Java 客户端框架,它把 Redis 的底层命令封装成了 Java 开发者熟悉的数据结构和工具(锁、队列、Map、信号量等),让你像使用本地 Java 对象一样使用分布式功能。

1.2 类比理解

你熟悉的Redisson 提供的区别
java.util.HashMapRMap(分布式Map)数据存在 Redis,多个服务实例共享
java.util.concurrent.locks.ReentrantLockRLock(分布式锁)锁存在 Redis,跨JVM生效
java.util.concurrent.BlockingQueueRBlockingQueue(分布式队列)队列存在 Redis,多实例消费
java.util.concurrent.SemaphoreRSemaphore(分布式信号量)信号量存在 Redis,跨实例限流

简单说:Redisson = Redis + Java 并发工具包的分布式版本。

1.3 Redisson vs Jedis vs Lettuce

框架定位特点
JedisRedis 底层客户端直接发送 Redis 命令,简单轻量
LettuceRedis 底层客户端基于 Netty,支持异步,Spring Boot 默认
RedissonRedis 高级客户端封装了分布式锁、集合、队列等高级功能
// Jedis:直接操作 Redis 命令jedis.set("key","value");jedis.setnx("lock-key","holder");// Lettuce(通过 Spring RedisTemplate):也是操作命令redisTemplate.opsForValue().set("key","value");redisTemplate.opsForValue().setIfAbsent("lock-key","holder");// Redisson:面向对象的方式,屏蔽底层命令RLocklock=redissonClient.getLock("lock-key");lock.lock();// 内部自动处理 SETNX、过期时间、看门狗等

二、为什么需要 Redisson

2.1 自己实现分布式锁的痛点

如果用 Jedis/Lettuce 自己实现分布式锁,需要处理:

// 自己实现:代码量大,容易出错publicbooleantryLock(Stringkey,StringholderId,longtimeout){// 1. 加锁(SETNX + 过期时间,必须原子操作)Booleansuccess=redisTemplate.opsForValue().setIfAbsent(key,holderId,timeout,TimeUnit.SECONDS);returnBoolean.TRUE.equals(success);}publicvoidunlock(Stringkey,StringholderId){// 2. 释放锁(必须验证持有者,必须用 Lua 脚本保证原子性)Stringscript="if redis.call('get',KEYS[1]) == ARGV[1] then "+"return redis.call('del',KEYS[1]) else return 0 end";redisTemplate.execute(newDefaultRedisScript<>(script,Long.class),Collections.singletonList(key),holderId);}// 3. 还需要自己实现:// - 看门狗续期// - 可重入支持// - 公平锁// - 红锁(RedLock)// - 异步加锁// - 锁的监听和通知

2.2 Redisson 帮你做了什么

// Redisson:一行代码搞定,内部自动处理所有细节RLocklock=redissonClient.getLock("my-lock");lock.lock();try{// 业务逻辑}finally{lock.unlock();}

Redisson 内部自动处理了:

  • 加锁的原子性(Lua 脚本)
  • 释放锁的持有者验证
  • 看门狗自动续期
  • 可重入计数
  • 等待队列和公平性
  • 集群/哨兵模式的兼容

注:

博客:

https://blog.csdn.net/badao_liumang_qizhi

三、快速上手

3.1 引入依赖

<!-- Maven --><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.27.0</version></dependency>

3.2 配置连接

# application.ymlspring:redis:host:127.0.0.1port:6379password:your-password

或者使用 Redisson 自己的配置:

# redisson.ymlsingleServerConfig:address:"redis://127.0.0.1:6379"password:"your-password"connectionMinimumIdleSize:5connectionPoolSize:10

3.3 注入使用

@ServicepublicclassOrderServiceImplimplementsOrderService{@ResourceprivateRedissonClientredissonClient;publicvoidprocessOrder(IntegerorderId){// 获取锁对象(此时还没有加锁)RLocklock=redissonClient.getLock("order-"+orderId);try{// 加锁:等待10秒,锁自动30秒过期booleanacquired=lock.tryLock(10,30,TimeUnit.SECONDS);if(!acquired){thrownewRuntimeException("获取锁失败");}// 执行业务doProcess(orderId);}catch(InterruptedExceptione){Thread.currentThread().interrupt();}finally{// 释放锁if(lock.isHeldByCurrentThread()){lock.unlock();}}}}

四、Redisson 核心功能详解

4.1 分布式锁(RLock)

这是 Redisson 最常用的功能。

RLocklock=redissonClient.getLock("my-lock");// 方式一:阻塞加锁(一直等到获取成功)lock.lock();// 方式二:尝试加锁(等待指定时间)booleansuccess=lock.tryLock(10,TimeUnit.SECONDS);// 方式三:尝试加锁 + 指定锁过期时间booleansuccess=lock.tryLock(10,30,TimeUnit.SECONDS);// 参数1:最多等10秒// 参数2:锁30秒后自动释放(不启用看门狗)// 方式四:尝试加锁 + 看门狗自动续期booleansuccess=lock.tryLock(10,TimeUnit.SECONDS);// 不指定第二个参数 → 启用看门狗,锁不会自动过期// 释放锁lock.unlock();

4.2 公平锁(RFairLock)

普通锁是"谁抢到算谁的",公平锁是"先来先得"。

// 公平锁:按请求顺序获取锁RLockfairLock=redissonClient.getFairLock("fair-lock");fairLock.lock();try{// 业务逻辑}finally{fairLock.unlock();}

4.3 读写锁(RReadWriteLock)

允许多个线程同时读,但写的时候独占。

RReadWriteLockrwLock=redissonClient.getReadWriteLock("rw-lock");// 读锁:多个线程可以同时持有RLockreadLock=rwLock.readLock();readLock.lock();try{// 读取数据(多个线程可以同时读)returndataRepository.findById(id);}finally{readLock.unlock();}// 写锁:独占,其他读和写都要等待RLockwriteLock=rwLock.writeLock();writeLock.lock();try{// 修改数据(独占)dataRepository.save(data);}finally{writeLock.unlock();}

4.4 分布式Map(RMap)

// 像使用 HashMap 一样,但数据存在 RedisRMap<String,UserInfo>userCache=redissonClient.getMap("user-cache");// 存入userCache.put("user-123",userInfo);// 读取UserInfoinfo=userCache.get("user-123");// 设置过期时间userCache.put("user-123",userInfo,30,TimeUnit.MINUTES);

4.5 分布式队列(RBlockingQueue)

// 生产者RBlockingQueue<String>queue=redissonClient.getBlockingQueue("task-queue");queue.offer("task-001");// 消费者(阻塞等待)Stringtask=queue.take();// 如果队列为空,会阻塞等待processTask(task);

4.6 限流器(RRateLimiter)

// 创建限流器:每秒最多10个请求RRateLimiterlimiter=redissonClient.getRateLimiter("api-limiter");limiter.trySetRate(RateType.OVERALL,10,1,RateIntervalUnit.SECONDS);// 使用if(limiter.tryAcquire()){// 允许通过processRequest();}else{// 被限流thrownewRuntimeException("请求过于频繁");}

五、RLock 的内部原理

5.1 加锁过程

Redisson 加锁时执行的 Lua 脚本(简化版):

-- 如果锁不存在ifredis.call('exists',KEYS[1])==0then-- 创建锁,设置持有者和重入计数redis.call('hset',KEYS[1],ARGV[2],1)-- 设置过期时间redis.call('pexpire',KEYS[1],ARGV[1])returnnilend-- 如果锁存在且是自己持有的(可重入)ifredis.call('hexists',KEYS[1],ARGV[2])==1then-- 重入计数+1redis.call('hincrby',KEYS[1],ARGV[2],1)-- 重置过期时间redis.call('pexpire',KEYS[1],ARGV[1])returnnilend-- 锁被别人持有,返回剩余过期时间returnredis.call('pttl',KEYS[1])

5.2 Redis 中锁的数据结构

Key: "my-lock" Type: Hash Value: "holder-id-thread-1" → 2 (重入计数=2,表示加了2次锁) TTL: 30000ms

5.3 释放锁过程

-- 检查锁是否是自己持有的ifredis.call('hexists',KEYS[1],ARGV[1])==0thenreturnnil-- 不是自己的锁,不操作end-- 重入计数-1localcounter=redis.call('hincrby',KEYS[1],ARGV[1],-1)ifcounter>0then-- 还有重入,只重置过期时间redis.call('pexpire',KEYS[1],ARGV[2])return0else-- 计数归零,真正释放锁redis.call('del',KEYS[1])-- 通知等待的线程redis.call('publish',KEYS[2],ARGV[3])return1end

六、Redisson 与 Spring Boot 集成

6.1 自动配置(最简方式)

引入redisson-spring-boot-starter后,Redisson 会自动读取spring.redis配置创建RedissonClient

@ServicepublicclassMyService{@ResourceprivateRedissonClientredissonClient;// 自动注入publicvoiddoSomething(){RLocklock=redissonClient.getLock("key");// ...}}

6.2 手动配置(需要自定义参数时)

@ConfigurationpublicclassRedissonConfig{@BeanpublicRedissonClientredissonClient(){Configconfig=newConfig();config.useSingleServer().setAddress("redis://127.0.0.1:6379").setPassword("password").setConnectionMinimumIdleSize(5).setConnectionPoolSize(20).setTimeout(3000).setRetryAttempts(3);returnRedisson.create(config);}}

6.3 集群模式配置

@BeanpublicRedissonClientredissonClient(){Configconfig=newConfig();config.useClusterServers().addNodeAddress("redis://node1:6379","redis://node2:6379","redis://node3:6379").setPassword("password");returnRedisson.create(config);}

七、实战示例:商品库存扣减

7.1 完整代码

/** * 库存服务实现. */@ServicepublicclassStockServiceImplimplementsStockService{@ResourceprivateRedissonClientredissonClient;@ResourceprivateStockRepositorystockRepository;/** * 扣减库存(使用分布式锁防止超卖). * * @param skuId 商品SKU ID * @param quantity 扣减数量 * @return true=扣减成功,false=库存不足 */@Transactional(rollbackFor=Exception.class)publicbooleandeductStock(IntegerskuId,Integerquantity){// 按SKU维度加锁StringlockKey="stock-deduct-"+skuId;RLocklock=redissonClient.getLock(lockKey);try{// 等待5秒,不指定leaseTime(启用看门狗)booleanacquired=lock.tryLock(5,TimeUnit.SECONDS);if(!acquired){log.warn("获取库存锁超时, skuId:{}",skuId);returnfalse;}// 查询当前库存Stockstock=stockRepository.findBySkuId(skuId);if(stock==null||stock.getQuantity()<quantity){log.info("库存不足, skuId:{}, 当前:{}, 需要:{}",skuId,stock==null?0:stock.getQuantity(),quantity);returnfalse;}// 扣减库存stock.setQuantity(stock.getQuantity()-quantity);stockRepository.save(stock);log.info("库存扣减成功, skuId:{}, 扣减:{}, 剩余:{}",skuId,quantity,stock.getQuantity());returntrue;}catch(InterruptedExceptione){Thread.currentThread().interrupt();log.warn("获取库存锁被中断, skuId:{}",skuId);returnfalse;}finally{// 释放锁if(lock.isHeldByCurrentThread()){lock.unlock();}}}}

7.2 关键代码解读

// 1. getLock("key") — 获取锁对象(还没加锁)RLocklock=redissonClient.getLock(lockKey);// 2. tryLock(waitTime) — 尝试加锁// - 如果锁空闲:立即获取,返回 true// - 如果锁被占用:等待最多5秒// - 5秒内锁释放了:获取成功,返回 true// - 5秒后仍被占用:放弃,返回 falsebooleanacquired=lock.tryLock(5,TimeUnit.SECONDS);// 3. isHeldByCurrentThread() — 检查当前线程是否持有锁// 防止释放别人的锁if(lock.isHeldByCurrentThread()){lock.unlock();}

八、Redisson 功能全景图

RedissonClient │ ├── 分布式锁 │ ├── RLock(可重入锁) │ ├── RFairLock(公平锁) │ ├── RReadWriteLock(读写锁) │ ├── RSemaphore(信号量) │ └── RCountDownLatch(倒计时门闩) │ ├── 分布式集合 │ ├── RMap(分布式Map) │ ├── RSet(分布式Set) │ ├── RList(分布式List) │ ├── RSortedSet(有序集合) │ └── RQueue / RBlockingQueue(队列) │ ├── 分布式服务 │ ├── RRemoteService(远程调用) │ ├── RScheduledExecutorService(定时任务) │ └── RExecutorService(分布式执行器) │ └── 其他工具 ├── RRateLimiter(限流器) ├── RAtomicLong(原子计数器) ├── RTopic(发布订阅) └── RBloomFilter(布隆过滤器)

九、常见问题

Q1:Redisson 和 Spring Cache 能一起用吗?

可以。Redisson 提供了 Spring Cache 的实现:

@Cacheable(cacheNames="userCache",key="#userId")publicUserInfogetUserById(IntegeruserId){returnuserRepository.findById(userId).orElse(null);}

Q2:Redisson 支持 Redis 集群吗?

支持。Redisson 支持单机、哨兵、集群、主从等所有 Redis 部署模式。

Q3:Redisson 的性能如何?

  • 加锁/释放锁:通常 1-3 毫秒(取决于网络延迟)
  • 比自己用 RedisTemplate 实现稍慢(多了一些内部逻辑)
  • 但比 ZooKeeper 实现快很多

Q4:项目中已经有 RedisTemplate 了,还需要 Redisson 吗?

两者可以共存。RedisTemplate 用于简单的缓存读写,Redisson 用于分布式锁、限流等高级功能。


十、总结

问题答案
Redisson 是什么?基于 Redis 的 Java 分布式工具框架
和 Jedis/Lettuce 的区别?Jedis/Lettuce 是底层客户端,Redisson 是高级封装
最常用的功能?分布式锁(RLock)
为什么不自己实现分布式锁?自己实现需要处理原子性、续期、可重入、持有者验证等细节
如何引入?redisson-spring-boot-starter依赖即可
性能影响?加锁/释放锁约 1-3ms,对大多数业务可忽略
http://www.jsqmd.com/news/886005/

相关文章:

  • 私有化视频会议解决方案/智能会议管理系统EasyDSS筑牢企业远程培训核心技术底座
  • Chromebook常用配置 - yi
  • Claude多方案对比评估深度复盘(企业级评估框架首次公开)
  • Python 3、VS Code、PyCharm 安装常见问题及解决方案大全(Windows/Mac/Linux)
  • 宁波梅雨季来临,房屋漏水抓紧修!2026最新房屋漏水维修公司TOP5调研盘点!卫生间免砸砖防水、楼顶外墙、阳光房+地下室渗漏解决方案解析 - 防水百科
  • 私有化视频会议系统EasyDSS一个平台,搞定直播、点播、作业、统计—学校终于不用买多套系统了
  • 蓝桥杯软件测试备考:用Python+Selenium搞定Web自动化那些高频考点(附完整代码)
  • TVA注意力层INT8量化配置技巧
  • 泰州梅雨季来临,房屋漏水抓紧修!2026最新房屋漏水维修公司TOP5调研盘点!卫生间免砸砖防水、楼顶外墙、阳光房+地下室渗漏解决方案解析 - 防水百科
  • 感谢雷总!Mimo大模型价值¥659/月的 MAX 套餐,让我免费领到了!
  • Nodejs后端服务如何集成Taotoken实现多模型智能对话
  • 虚幻5 Unrealsharp EditorTick + Nanite雪地踩坑记录
  • http响应的 headers中拿到文件名
  • 开源权重、商业闭源、衍生模型——DeepSeek知识产权边界全解析,一文厘清5类侵权陷阱
  • Jira 自动化语言编码双计数器机器:实现加法与斐波那契数列运算,具备图灵完备性
  • 如何快速搭建ROS机器人仿真环境:完整实战指南
  • 开发多语言翻译服务时如何利用多模型能力优化效果与成本
  • 2026年5月西安GEO优化服务商TOP5:AI搜索与豆包排名实战推荐 - 资讯快报
  • 嵌入式工程师代码能力综合评估标准
  • 5个步骤掌握FanControl:Windows风扇控制终极静音方案
  • 2026年国内金融科技五大排行:融资担保信息系统公司深度解析 - 十大品牌榜
  • 打造XBEE封装BLE112蓝牙模块:硬件设计、射频布局与调试全攻略
  • 鸣潮工具箱WaveTools:游戏体验优化的终极免费解决方案
  • Android Framework P4 - ServiceManager 进程
  • LaTeX公式一键转Word:3步告别数学公式编辑烦恼
  • 2026年横评10款降AIGC网站:一键锁定高效助手!
  • 终极指南:5步快速定位Windows热键冲突元凶
  • 诚信标签工厂端落地技术方案 多品类俄标追溯采集应用分析
  • 独家专访杨元庆:详解联想集团千亿美金营收目标
  • 观察taotoken在多模型间自动路由对api调用成功率的影响