使用 **Redisson** 作为 Redis 客户端时,需要注意以下几点,以确保代码的稳定性、性能和可维护性:
---
## 1. **线程安全与连接池配置**
Redisson 的 `RedissonClient` 是线程安全的,可以在多个线程中共享使用。
### 建议配置连接池:
```yaml
# redisson-config.yml
singleServerConfig:
address: "redis://127.0.0.1:6379"
password: null
database: 0
connectionPoolSize: 64 # 连接池大小
connectionMinimumIdleSize: 24
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
```
### 使用方式:
```java
@Configuration
public class RedissonConfig {
@Bean
public RedissonClient redissonClient() {
Config config = Config.fromYAML(getClass().getResourceAsStream("/redisson-config.yml"));
return Redisson.create(config);
}
}
```
---
## 2. **资源释放与生命周期管理**
- `RedissonClient` 实例在整个应用生命周期中只需创建一次,**不要频繁创建和关闭**。
- 应用关闭时应优雅关闭 Redisson 客户端:
```java
@PreDestroy
public void destroy() {
if (redissonClient != null) {
redissonClient.shutdown();
}
}
```
---
## 3. **使用 RBucket 获取和设置数据**
### 示例:
```java
@Autowired
private RedissonClient redissonClient;
public String get(String key) {
RBucket<String> bucket = redissonClient.getBucket(key);
return bucket.get();
}
public void set(String key, String value) {
RBucket<String> bucket = redissonClient.getBucket(key);
bucket.set(value);
}
```
---
## 4. **使用 RMap 缓存对象结构数据**
如果你要存储 JSON 对象,可以使用 `RMap`:
```java
public void saveUserInfo(String key, UserInfoVo userInfo) {
RMap<String, Object> map = redissonClient.getMap(key);
map.putAll(userInfoToMap(userInfo));
map.expire(30, TimeUnit.MINUTES); // 设置过期时间
}
private Map<String, Object> userInfoToMap(UserInfoVo vo) {
Map<String, Object> result = new HashMap<>();
result.put("userId", vo.getUserId());
result.put("username", vo.getUsername());
result.put("orgId", vo.getOrgId());
result.put("roleId", vo.getRoleId());
return result;
}
```
---
## 5. **分布式锁的使用**
Redisson 提供了强大的分布式锁实现:
```java
RLock lock = redissonClient.getLock("lockKey");
try {
if (lock.tryLock()) {
// 执行业务逻辑
}
} finally {
lock.unlock();
}
```
---
## 6. **JSON 序列化/反序列化**
Redisson 默认使用 `Jackson`,但你也可以自定义序列化方式。
### 示例:使用 Jackson 解析 JSON
```java
ObjectMapper objectMapper = new ObjectMapper();
public <T> T getJson(String key, Class<T> clazz) throws JsonProcessingException {
String json = get(key);
return json == null ? null : objectMapper.readValue(json, clazz);
}
public <T> void setJson(String key, T value) throws JsonProcessingException {
String json = objectMapper.writeValueAsString(value);
set(key, json);
}
```
---
## 7. **异常处理**
Redisson 操作可能抛出异常(如 Redis 连接失败),应合理捕获并处理:
```java
try {
String value = get("user:1001");
} catch (Exception e) {
// 记录日志、重试或返回默认值
log.error("Redisson 获取数据失败", e);
}
```
---
## 8. **性能优化建议**
- **避免频繁访问 Redis**:可以结合本地缓存(如 Caffeine)做二级缓存。
- **使用异步方法**:Redisson 支持异步操作(如 `getAsync`, `putAsync`),适用于高并发场景。
- **设置合理的 TTL**:避免 Redis 内存无限增长。
---
## 9. **集群和哨兵支持**
Redisson 支持 Redis 集群、哨兵模式等高级用法:
```yaml
clusterServersConfig:
nodes:
- "redis://192.168.1.1:6379"
- "redis://192.168.1.2:6379"
password: null
```
---
## 10. **日志与监控**
- 开启 Redisson 的日志输出,方便排查问题。
- 可集成 Prometheus + Grafana 监控 Redisson 客户端状态(连接数、等待线程数等)。
---
## 总结:使用 Redisson 的最佳实践
| 项目 | 建议 |
|------|------|
| 客户端管理 | 单例模式,整个应用共享一个 `RedissonClient` |
| 线程安全 | 不需要额外同步,RedissonClient 是线程安全的 |
| 资源释放 | 应用关闭时调用 [shutdown()](file://D:\develop\prod\Dealer-base-service\dealer-modules\dealer-manager\src\main\java\com\yili\dealer\utils\ThreadPoolUtil.java#L61-L65) |
| 分布式锁 | 使用 `RLock` 实现 |
| 数据结构 | 优先使用 `RBucket`, `RMap`, `RList` 等封装 |
| 序列化 | 使用 Jackson,避免使用默认的 JDK 序列化 |
| 异常处理 | 捕获 Redis 异常并做降级处理 |
| 性能优化 | 设置连接池、合理使用 TTL 和本地缓存 |
| 集群支持 | 使用 `clusterServersConfig` 配置 Redis 集群 |
| 日志监控 | 集成日志系统和监控平台 |
---
如果你希望我帮你:
- 封装通用的 Redisson 工具类
- 实现基于 Redisson 的用户登录状态管理
- 实现 Redisson 分布式锁的封装
- 实现 Redisson + Spring Boot 的自动配置
欢迎继续提问!