一、创建 Spring Boot 项目并集成 Redisson
- 添加依赖
在pom.xml
中添加 Redisson 和 Spring Boot 依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.23.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
- 配置 Redisson 连接
在application.properties
中添加 Redis 连接信息:
# Redis服务器地址
spring.redis.host=localhost
spring.redis.port=6379
# 可选:密码和数据库
# spring.redis.password=yourpassword
# spring.redis.database=0
二、实现分布式锁示例
- 创建 Service 类
在src/main/java/com/example/redissondemo/service
包下创建DistributedLockService
:
package com.example.redissondemo.service;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Service
public class DistributedLockService {
@Autowired
private RedissonClient redissonClient;
/**
* 分布式锁示例:模拟商品库存扣减
*/
public void deductStock() {
String lockKey = "product_001";
RLock lock = redissonClient.getLock(lockKey);
try {
// 尝试获取锁,等待10秒,自动释放时间30秒
boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);
if (isLocked) {
// 获得锁后执行临界区代码
System.out.println("线程 " + Thread.currentThread().getId() + " 获得锁");
// 模拟业务操作:扣减库存
// ...
Thread.sleep(5000); // 模拟业务耗时
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
// 释放锁
if (lock.isHeldByCurrentThread()) {
lock.unlock();
System.out.println("线程 " + Thread.currentThread().getId() + " 释放锁");
}
}
}
}
- 创建 Controller 测试接口
在src/main/java/com/example/redissondemo/controller
包下创建LockController
:
package com.example.redissondemo.controller;
import com.example.redissondemo.service.DistributedLockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/lock")
public class LockController {
@Autowired
private DistributedLockService lockService;
@GetMapping("/test")
public String testLock() {
lockService.deductStock();
return "操作完成";
}
}
三、实现分布式集合示例
- 创建分布式 Map 示例
在src/main/java/com/example/redissondemo/service
包下创建DistributedCollectionService
:
package com.example.redissondemo.service;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
@Service
public class DistributedCollectionService {
@Autowired
private RedissonClient redissonClient;
/**
* 分布式Map操作示例
*/
public void operateMap() {
// 获取分布式Map
RMap<String, String> map = redissonClient.getMap("myDistributedMap");
// 写入数据
map.put("key1", "value1");
map.put("key2", "value2");
// 读取数据
String value1 = map.get("key1");
System.out.println("key1的值: " + value1);
// 获取所有数据
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println("键: " + entry.getKey() + ", 值: " + entry.getValue());
}
// 删除数据
map.remove("key1");
}
}
- 创建 Controller 测试接口
在src/main/java/com/example/redissondemo/controller
包下创建CollectionController
:
package com.example.redissondemo.controller;
import com.example.redissondemo.service.DistributedCollectionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/collection")
public class CollectionController {
@Autowired
private DistributedCollectionService collectionService;
@GetMapping("/test")
public String testCollection() {
collectionService.operateMap();
return "集合操作完成";
}
}
四、Redisson 实现原理分析
1. 分布式锁实现原理
Redisson 的分布式锁基于 Redis 的原子操作实现,核心原理如下:
-
加锁机制:
使用SET key value NX PX
命令原子性地设置锁,只有当键不存在时才能设置成功。锁的值是一个唯一标识(UUID + 线程 ID),用于区分不同的客户端。 -
锁续约机制(看门狗):
Redisson 默认会为锁设置一个超时时间(默认 30 秒),并启动一个后台线程(看门狗)不断延长锁的超时时间。只要持有锁的客户端没有崩溃,锁就不会过期。 -
释放锁机制:
使用 Lua 脚本原子性地检查锁的持有者并删除锁,确保操作的原子性。
2. 通信机制
Redisson 通过 Netty 框架实现与 Redis 的异步通信,支持多种连接模式:
- 单节点模式
- 主从模式
- 哨兵模式
- 集群模式
3. 序列化机制
Redisson 支持多种序列化方式,默认使用 Jackson JSON 序列化,确保对象可以在不同客户端之间正确传递。
五、Redisson 的优势
-
丰富的分布式对象
提供了分布式锁、分布式集合、分布式队列等多种数据结构,简化分布式系统开发。 -
可重入锁支持
同一个线程可以多次获取同一把锁,避免死锁。 -
公平锁实现
支持公平锁,保证锁的获取顺序遵循请求的先后顺序。 -
锁续约机制
自动延长锁的超时时间,避免业务处理时间过长导致锁提前释放。 -
异步和响应式编程支持
提供异步 API 和响应式 API,适合高并发场景。 -
集群和哨兵支持
无缝支持 Redis 集群和哨兵模式,提高系统可用性。
六、Redisson 的应用场景
-
分布式锁
- 库存扣减:防止超卖
- 分布式任务调度:避免重复执行
- 分布式 ID 生成器:保证唯一性
-
分布式集合
- 分布式缓存:共享数据
- 分布式计数器:统计在线人数、访问量等
- 分布式消息队列:基于 Redis 实现队列功能
-
分布式协调
- 分布式信号量:控制资源访问数量
- 分布式闭锁:协调多个服务的启动顺序
-
分布式缓存
- 实现分布式二级缓存,提高系统性能
七、测试和验证
-
启动 Redis 服务器
bash
redis-server
-
启动 Spring Boot 应用
运行主应用类的main
方法。 -
测试分布式锁
访问http://localhost:8080/api/lock/test
,观察控制台输出,确认锁的获取和释放顺序。 -
测试分布式集合
访问http://localhost:8080/api/collection/test
,确认数据能正确存储和读取。
八、注意事项
-
锁的粒度控制
尽量缩小锁的范围,减少锁持有时间,提高系统并发性能。 -
异常处理
确保在 finally 块中释放锁,避免锁泄漏。 -
性能考虑
Redis 是单线程处理命令,高并发场景下需注意性能瓶颈。 -
集群环境
在 Redis 集群环境中,需注意锁的一致性问题,Redisson 提供了 RedLock 算法解决此问题。