mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-09-18 09:35:29 +08:00
update Redisson version to 4.0.0
update 优化redis缓存key前缀处理器和多住户redis缓存key前缀处理器代码及其配置流程
This commit is contained in:
parent
f20a0c4342
commit
18afc3691b
13
pom.xml
13
pom.xml
@ -28,7 +28,7 @@
|
|||||||
<p6spy.version>3.9.1</p6spy.version>
|
<p6spy.version>3.9.1</p6spy.version>
|
||||||
<hutool.version>5.8.40</hutool.version>
|
<hutool.version>5.8.40</hutool.version>
|
||||||
<spring-boot-admin.version>3.5.5</spring-boot-admin.version>
|
<spring-boot-admin.version>3.5.5</spring-boot-admin.version>
|
||||||
<redisson.version>3.52.0</redisson.version>
|
<redisson.version>4.0.0</redisson.version>
|
||||||
<lock4j.version>2.2.7</lock4j.version>
|
<lock4j.version>2.2.7</lock4j.version>
|
||||||
<dynamic-ds.version>4.3.1</dynamic-ds.version>
|
<dynamic-ds.version>4.3.1</dynamic-ds.version>
|
||||||
<snailjob.version>1.8.0</snailjob.version>
|
<snailjob.version>1.8.0</snailjob.version>
|
||||||
@ -261,6 +261,17 @@
|
|||||||
<groupId>org.redisson</groupId>
|
<groupId>org.redisson</groupId>
|
||||||
<artifactId>redisson-spring-boot-starter</artifactId>
|
<artifactId>redisson-spring-boot-starter</artifactId>
|
||||||
<version>${redisson.version}</version>
|
<version>${redisson.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.redisson</groupId>
|
||||||
|
<artifactId>redisson-spring-data-40</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.redisson</groupId>
|
||||||
|
<artifactId>redisson-spring-data-35</artifactId>
|
||||||
|
<version>${redisson.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@ -107,29 +107,28 @@ spring.data:
|
|||||||
timeout: 10s
|
timeout: 10s
|
||||||
# 是否开启ssl
|
# 是否开启ssl
|
||||||
ssl.enabled: false
|
ssl.enabled: false
|
||||||
|
# redisson 配置 官方文档:https://redisson.pro/docs/integration-with-spring/#spring-boot-starter
|
||||||
# redisson 配置
|
redisson:
|
||||||
redisson:
|
# redis key前缀
|
||||||
# redis key前缀
|
keyPrefix:
|
||||||
keyPrefix:
|
# 线程池数量
|
||||||
# 线程池数量
|
threads: 4
|
||||||
threads: 4
|
# Netty线程池数量
|
||||||
# Netty线程池数量
|
nettyThreads: 8
|
||||||
nettyThreads: 8
|
# 单节点配置
|
||||||
# 单节点配置
|
singleServerConfig:
|
||||||
singleServerConfig:
|
# 客户端名称 不能用中文
|
||||||
# 客户端名称 不能用中文
|
clientName: RuoYi-Vue-Plus
|
||||||
clientName: RuoYi-Vue-Plus
|
# 最小空闲连接数
|
||||||
# 最小空闲连接数
|
connectionMinimumIdleSize: 8
|
||||||
connectionMinimumIdleSize: 8
|
# 连接池大小
|
||||||
# 连接池大小
|
connectionPoolSize: 32
|
||||||
connectionPoolSize: 32
|
# 连接空闲超时,单位:毫秒
|
||||||
# 连接空闲超时,单位:毫秒
|
idleConnectionTimeout: 10000
|
||||||
idleConnectionTimeout: 10000
|
# 命令等待超时,单位:毫秒
|
||||||
# 命令等待超时,单位:毫秒
|
timeout: 3000
|
||||||
timeout: 3000
|
# 发布和订阅连接池大小
|
||||||
# 发布和订阅连接池大小
|
subscriptionConnectionPoolSize: 50
|
||||||
subscriptionConnectionPoolSize: 50
|
|
||||||
|
|
||||||
--- # mail 邮件发送
|
--- # mail 邮件发送
|
||||||
mail:
|
mail:
|
||||||
|
|||||||
@ -110,29 +110,28 @@ spring.data:
|
|||||||
timeout: 10s
|
timeout: 10s
|
||||||
# 是否开启ssl
|
# 是否开启ssl
|
||||||
ssl.enabled: false
|
ssl.enabled: false
|
||||||
|
# redisson 配置 官方文档:https://redisson.pro/docs/integration-with-spring/#spring-boot-starter
|
||||||
# redisson 配置
|
redisson:
|
||||||
redisson:
|
# redis key前缀
|
||||||
# redis key前缀
|
keyPrefix:
|
||||||
keyPrefix:
|
# 线程池数量
|
||||||
# 线程池数量
|
threads: 16
|
||||||
threads: 16
|
# Netty线程池数量
|
||||||
# Netty线程池数量
|
nettyThreads: 32
|
||||||
nettyThreads: 32
|
# 单节点配置
|
||||||
# 单节点配置
|
singleServerConfig:
|
||||||
singleServerConfig:
|
# 客户端名称 不能用中文
|
||||||
# 客户端名称 不能用中文
|
clientName: RuoYi-Vue-Plus
|
||||||
clientName: RuoYi-Vue-Plus
|
# 最小空闲连接数
|
||||||
# 最小空闲连接数
|
connectionMinimumIdleSize: 32
|
||||||
connectionMinimumIdleSize: 32
|
# 连接池大小
|
||||||
# 连接池大小
|
connectionPoolSize: 64
|
||||||
connectionPoolSize: 64
|
# 连接空闲超时,单位:毫秒
|
||||||
# 连接空闲超时,单位:毫秒
|
idleConnectionTimeout: 10000
|
||||||
idleConnectionTimeout: 10000
|
# 命令等待超时,单位:毫秒
|
||||||
# 命令等待超时,单位:毫秒
|
timeout: 3000
|
||||||
timeout: 3000
|
# 发布和订阅连接池大小
|
||||||
# 发布和订阅连接池大小
|
subscriptionConnectionPoolSize: 50
|
||||||
subscriptionConnectionPoolSize: 50
|
|
||||||
|
|
||||||
--- # mail 邮件发送
|
--- # mail 邮件发送
|
||||||
mail:
|
mail:
|
||||||
|
|||||||
@ -27,6 +27,10 @@
|
|||||||
<groupId>org.redisson</groupId>
|
<groupId>org.redisson</groupId>
|
||||||
<artifactId>redisson-spring-boot-starter</artifactId>
|
<artifactId>redisson-spring-boot-starter</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.redisson</groupId>
|
||||||
|
<artifactId>redisson-spring-data-35</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.baomidou</groupId>
|
<groupId>com.baomidou</groupId>
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
package org.dromara.common.redis.config;
|
package org.dromara.common.redis.config;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
@ -10,16 +9,14 @@ import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
|||||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.common.core.utils.SpringUtils;
|
import org.dromara.common.core.utils.SpringUtils;
|
||||||
import org.dromara.common.redis.config.properties.RedissonProperties;
|
|
||||||
import org.dromara.common.redis.handler.KeyPrefixHandler;
|
import org.dromara.common.redis.handler.KeyPrefixHandler;
|
||||||
import org.dromara.common.redis.handler.RedisExceptionHandler;
|
import org.dromara.common.redis.handler.RedisExceptionHandler;
|
||||||
import org.redisson.client.codec.StringCodec;
|
import org.redisson.client.codec.StringCodec;
|
||||||
import org.redisson.codec.CompositeCodec;
|
import org.redisson.codec.CompositeCodec;
|
||||||
import org.redisson.codec.TypedJsonJacksonCodec;
|
import org.redisson.codec.TypedJsonJacksonCodec;
|
||||||
import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
|
import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.core.task.VirtualThreadTaskExecutor;
|
import org.springframework.core.task.VirtualThreadTaskExecutor;
|
||||||
|
|
||||||
@ -34,11 +31,13 @@ import java.util.TimeZone;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@AutoConfiguration
|
@AutoConfiguration
|
||||||
@EnableConfigurationProperties(RedissonProperties.class)
|
|
||||||
public class RedisConfig {
|
public class RedisConfig {
|
||||||
|
|
||||||
@Autowired
|
/**
|
||||||
private RedissonProperties redissonProperties;
|
* redis缓存key前缀
|
||||||
|
*/
|
||||||
|
@Value("${spring.data.redis.redisson.keyPrefix}")
|
||||||
|
private String keyPrefix;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public RedissonAutoConfigurationCustomizer redissonCustomizer() {
|
public RedissonAutoConfigurationCustomizer redissonCustomizer() {
|
||||||
@ -60,44 +59,11 @@ public class RedisConfig {
|
|||||||
TypedJsonJacksonCodec jsonCodec = new TypedJsonJacksonCodec(Object.class, om);
|
TypedJsonJacksonCodec jsonCodec = new TypedJsonJacksonCodec(Object.class, om);
|
||||||
// 组合序列化 key 使用 String 内容使用通用 json 格式
|
// 组合序列化 key 使用 String 内容使用通用 json 格式
|
||||||
CompositeCodec codec = new CompositeCodec(StringCodec.INSTANCE, jsonCodec, jsonCodec);
|
CompositeCodec codec = new CompositeCodec(StringCodec.INSTANCE, jsonCodec, jsonCodec);
|
||||||
config.setThreads(redissonProperties.getThreads())
|
config.setCodec(codec);
|
||||||
.setNettyThreads(redissonProperties.getNettyThreads())
|
|
||||||
// 缓存 Lua 脚本 减少网络传输(redisson 大部分的功能都是基于 Lua 脚本实现)
|
|
||||||
.setUseScriptCache(true)
|
|
||||||
.setCodec(codec);
|
|
||||||
if (SpringUtils.isVirtual()) {
|
if (SpringUtils.isVirtual()) {
|
||||||
config.setNettyExecutor(new VirtualThreadTaskExecutor("redisson-"));
|
config.setNettyExecutor(new VirtualThreadTaskExecutor("redisson-"));
|
||||||
}
|
}
|
||||||
RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig();
|
config.setNameMapper(new KeyPrefixHandler(keyPrefix));
|
||||||
if (ObjectUtil.isNotNull(singleServerConfig)) {
|
|
||||||
// 使用单机模式
|
|
||||||
config.useSingleServer()
|
|
||||||
//设置redis key前缀
|
|
||||||
.setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
|
|
||||||
.setTimeout(singleServerConfig.getTimeout())
|
|
||||||
.setClientName(singleServerConfig.getClientName())
|
|
||||||
.setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout())
|
|
||||||
.setSubscriptionConnectionPoolSize(singleServerConfig.getSubscriptionConnectionPoolSize())
|
|
||||||
.setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize())
|
|
||||||
.setConnectionPoolSize(singleServerConfig.getConnectionPoolSize());
|
|
||||||
}
|
|
||||||
// 集群配置方式 参考下方注释
|
|
||||||
RedissonProperties.ClusterServersConfig clusterServersConfig = redissonProperties.getClusterServersConfig();
|
|
||||||
if (ObjectUtil.isNotNull(clusterServersConfig)) {
|
|
||||||
config.useClusterServers()
|
|
||||||
//设置redis key前缀
|
|
||||||
.setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
|
|
||||||
.setTimeout(clusterServersConfig.getTimeout())
|
|
||||||
.setClientName(clusterServersConfig.getClientName())
|
|
||||||
.setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout())
|
|
||||||
.setSubscriptionConnectionPoolSize(clusterServersConfig.getSubscriptionConnectionPoolSize())
|
|
||||||
.setMasterConnectionMinimumIdleSize(clusterServersConfig.getMasterConnectionMinimumIdleSize())
|
|
||||||
.setMasterConnectionPoolSize(clusterServersConfig.getMasterConnectionPoolSize())
|
|
||||||
.setSlaveConnectionMinimumIdleSize(clusterServersConfig.getSlaveConnectionMinimumIdleSize())
|
|
||||||
.setSlaveConnectionPoolSize(clusterServersConfig.getSlaveConnectionPoolSize())
|
|
||||||
.setReadMode(clusterServersConfig.getReadMode())
|
|
||||||
.setSubscriptionMode(clusterServersConfig.getSubscriptionMode());
|
|
||||||
}
|
|
||||||
log.info("初始化 redis 配置");
|
log.info("初始化 redis 配置");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -127,34 +93,34 @@ public class RedisConfig {
|
|||||||
* timeout: 10s
|
* timeout: 10s
|
||||||
* # 是否开启ssl
|
* # 是否开启ssl
|
||||||
* ssl.enabled: false
|
* ssl.enabled: false
|
||||||
*
|
* # redisson配置
|
||||||
* redisson:
|
* redisson:
|
||||||
* # 线程池数量
|
* # 线程池数量
|
||||||
* threads: 16
|
* threads: 16
|
||||||
* # Netty线程池数量
|
* # Netty线程池数量
|
||||||
* nettyThreads: 32
|
* nettyThreads: 32
|
||||||
* # 集群配置
|
* # 集群配置
|
||||||
* clusterServersConfig:
|
* clusterServersConfig:
|
||||||
* # 客户端名称
|
* # 客户端名称
|
||||||
* clientName: ${ruoyi.name}
|
* clientName: ${ruoyi.name}
|
||||||
* # master最小空闲连接数
|
* # master最小空闲连接数
|
||||||
* masterConnectionMinimumIdleSize: 32
|
* masterConnectionMinimumIdleSize: 32
|
||||||
* # master连接池大小
|
* # master连接池大小
|
||||||
* masterConnectionPoolSize: 64
|
* masterConnectionPoolSize: 64
|
||||||
* # slave最小空闲连接数
|
* # slave最小空闲连接数
|
||||||
* slaveConnectionMinimumIdleSize: 32
|
* slaveConnectionMinimumIdleSize: 32
|
||||||
* # slave连接池大小
|
* # slave连接池大小
|
||||||
* slaveConnectionPoolSize: 64
|
* slaveConnectionPoolSize: 64
|
||||||
* # 连接空闲超时,单位:毫秒
|
* # 连接空闲超时,单位:毫秒
|
||||||
* idleConnectionTimeout: 10000
|
* idleConnectionTimeout: 10000
|
||||||
* # 命令等待超时,单位:毫秒
|
* # 命令等待超时,单位:毫秒
|
||||||
* timeout: 3000
|
* timeout: 3000
|
||||||
* # 发布和订阅连接池大小
|
* # 发布和订阅连接池大小
|
||||||
* subscriptionConnectionPoolSize: 50
|
* subscriptionConnectionPoolSize: 50
|
||||||
* # 读取模式
|
* # 读取模式
|
||||||
* readMode: "SLAVE"
|
* readMode: "SLAVE"
|
||||||
* # 订阅模式
|
* # 订阅模式
|
||||||
* subscriptionMode: "MASTER"
|
* subscriptionMode: "MASTER"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,135 +0,0 @@
|
|||||||
package org.dromara.common.redis.config.properties;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import org.redisson.config.ReadMode;
|
|
||||||
import org.redisson.config.SubscriptionMode;
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redisson 配置属性
|
|
||||||
*
|
|
||||||
* @author Lion Li
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@ConfigurationProperties(prefix = "redisson")
|
|
||||||
public class RedissonProperties {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* redis缓存key前缀
|
|
||||||
*/
|
|
||||||
private String keyPrefix;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 线程池数量,默认值 = 当前处理核数量 * 2
|
|
||||||
*/
|
|
||||||
private int threads;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Netty线程池数量,默认值 = 当前处理核数量 * 2
|
|
||||||
*/
|
|
||||||
private int nettyThreads;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 单机服务配置
|
|
||||||
*/
|
|
||||||
private SingleServerConfig singleServerConfig;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 集群服务配置
|
|
||||||
*/
|
|
||||||
private ClusterServersConfig clusterServersConfig;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@NoArgsConstructor
|
|
||||||
public static class SingleServerConfig {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 客户端名称
|
|
||||||
*/
|
|
||||||
private String clientName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 最小空闲连接数
|
|
||||||
*/
|
|
||||||
private int connectionMinimumIdleSize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 连接池大小
|
|
||||||
*/
|
|
||||||
private int connectionPoolSize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 连接空闲超时,单位:毫秒
|
|
||||||
*/
|
|
||||||
private int idleConnectionTimeout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 命令等待超时,单位:毫秒
|
|
||||||
*/
|
|
||||||
private int timeout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发布和订阅连接池大小
|
|
||||||
*/
|
|
||||||
private int subscriptionConnectionPoolSize;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@NoArgsConstructor
|
|
||||||
public static class ClusterServersConfig {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 客户端名称
|
|
||||||
*/
|
|
||||||
private String clientName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* master最小空闲连接数
|
|
||||||
*/
|
|
||||||
private int masterConnectionMinimumIdleSize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* master连接池大小
|
|
||||||
*/
|
|
||||||
private int masterConnectionPoolSize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* slave最小空闲连接数
|
|
||||||
*/
|
|
||||||
private int slaveConnectionMinimumIdleSize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* slave连接池大小
|
|
||||||
*/
|
|
||||||
private int slaveConnectionPoolSize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 连接空闲超时,单位:毫秒
|
|
||||||
*/
|
|
||||||
private int idleConnectionTimeout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 命令等待超时,单位:毫秒
|
|
||||||
*/
|
|
||||||
private int timeout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发布和订阅连接池大小
|
|
||||||
*/
|
|
||||||
private int subscriptionConnectionPoolSize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取模式
|
|
||||||
*/
|
|
||||||
private ReadMode readMode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订阅模式
|
|
||||||
*/
|
|
||||||
private SubscriptionMode subscriptionMode;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package org.dromara.common.redis.handler;
|
package org.dromara.common.redis.handler;
|
||||||
|
|
||||||
import org.dromara.common.core.utils.StringUtils;
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
import org.redisson.api.NameMapper;
|
import org.redisson.config.NameMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* redis缓存key前缀处理
|
* redis缓存key前缀处理
|
||||||
@ -24,9 +24,6 @@ public class KeyPrefixHandler implements NameMapper {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String map(String name) {
|
public String map(String name) {
|
||||||
if (StringUtils.isBlank(name)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (StringUtils.isNotBlank(keyPrefix) && !name.startsWith(keyPrefix)) {
|
if (StringUtils.isNotBlank(keyPrefix) && !name.startsWith(keyPrefix)) {
|
||||||
return keyPrefix + name;
|
return keyPrefix + name;
|
||||||
}
|
}
|
||||||
@ -38,9 +35,6 @@ public class KeyPrefixHandler implements NameMapper {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String unmap(String name) {
|
public String unmap(String name) {
|
||||||
if (StringUtils.isBlank(name)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (StringUtils.isNotBlank(keyPrefix) && name.startsWith(keyPrefix)) {
|
if (StringUtils.isNotBlank(keyPrefix) && name.startsWith(keyPrefix)) {
|
||||||
return name.substring(keyPrefix.length());
|
return name.substring(keyPrefix.length());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,14 @@
|
|||||||
package org.dromara.common.tenant.config;
|
package org.dromara.common.tenant.config;
|
||||||
|
|
||||||
import cn.dev33.satoken.dao.SaTokenDao;
|
import cn.dev33.satoken.dao.SaTokenDao;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
|
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
|
||||||
import org.dromara.common.core.utils.reflect.ReflectUtils;
|
|
||||||
import org.dromara.common.redis.config.RedisConfig;
|
import org.dromara.common.redis.config.RedisConfig;
|
||||||
import org.dromara.common.redis.config.properties.RedissonProperties;
|
import org.dromara.common.redis.handler.KeyPrefixHandler;
|
||||||
import org.dromara.common.tenant.core.TenantSaTokenDao;
|
import org.dromara.common.tenant.core.TenantSaTokenDao;
|
||||||
import org.dromara.common.tenant.handle.PlusTenantLineHandler;
|
import org.dromara.common.tenant.handle.PlusTenantLineHandler;
|
||||||
import org.dromara.common.tenant.handle.TenantKeyPrefixHandler;
|
import org.dromara.common.tenant.handle.TenantKeyPrefixHandler;
|
||||||
import org.dromara.common.tenant.manager.TenantSpringCacheManager;
|
import org.dromara.common.tenant.manager.TenantSpringCacheManager;
|
||||||
import org.dromara.common.tenant.properties.TenantProperties;
|
import org.dromara.common.tenant.properties.TenantProperties;
|
||||||
import org.redisson.config.ClusterServersConfig;
|
|
||||||
import org.redisson.config.SingleServerConfig;
|
|
||||||
import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
|
import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
@ -47,20 +43,11 @@ public class TenantConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public RedissonAutoConfigurationCustomizer tenantRedissonCustomizer(RedissonProperties redissonProperties) {
|
public RedissonAutoConfigurationCustomizer tenantRedissonCustomizer() {
|
||||||
return config -> {
|
return config -> {
|
||||||
TenantKeyPrefixHandler nameMapper = new TenantKeyPrefixHandler(redissonProperties.getKeyPrefix());
|
if (config.getNameMapper() instanceof KeyPrefixHandler handler) {
|
||||||
SingleServerConfig singleServerConfig = ReflectUtils.invokeGetter(config, "singleServerConfig");
|
// 使用多租户redis缓存key前缀处理器
|
||||||
if (ObjectUtil.isNotNull(singleServerConfig)) {
|
config.setNameMapper(new TenantKeyPrefixHandler(handler));
|
||||||
// 使用单机模式
|
|
||||||
// 设置多租户 redis key前缀
|
|
||||||
singleServerConfig.setNameMapper(nameMapper);
|
|
||||||
}
|
|
||||||
ClusterServersConfig clusterServersConfig = ReflectUtils.invokeGetter(config, "clusterServersConfig");
|
|
||||||
// 集群配置方式 参考下方注释
|
|
||||||
if (ObjectUtil.isNotNull(clusterServersConfig)) {
|
|
||||||
// 设置多租户 redis key前缀
|
|
||||||
clusterServersConfig.setNameMapper(nameMapper);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import org.dromara.common.core.constant.GlobalConstants;
|
|||||||
import org.dromara.common.core.utils.StringUtils;
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
import org.dromara.common.redis.handler.KeyPrefixHandler;
|
import org.dromara.common.redis.handler.KeyPrefixHandler;
|
||||||
import org.dromara.common.tenant.helper.TenantHelper;
|
import org.dromara.common.tenant.helper.TenantHelper;
|
||||||
|
import org.redisson.config.NameMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 多租户redis缓存key前缀处理
|
* 多租户redis缓存key前缀处理
|
||||||
@ -13,10 +14,15 @@ import org.dromara.common.tenant.helper.TenantHelper;
|
|||||||
* @author Lion Li
|
* @author Lion Li
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class TenantKeyPrefixHandler extends KeyPrefixHandler {
|
public class TenantKeyPrefixHandler implements NameMapper {
|
||||||
|
|
||||||
public TenantKeyPrefixHandler(String keyPrefix) {
|
/**
|
||||||
super(keyPrefix);
|
* Key前缀处理器
|
||||||
|
*/
|
||||||
|
private final KeyPrefixHandler handler;
|
||||||
|
|
||||||
|
public TenantKeyPrefixHandler(KeyPrefixHandler handler) {
|
||||||
|
this.handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,28 +31,24 @@ public class TenantKeyPrefixHandler extends KeyPrefixHandler {
|
|||||||
@Override
|
@Override
|
||||||
public String map(String name) {
|
public String map(String name) {
|
||||||
if (StringUtils.isBlank(name)) {
|
if (StringUtils.isBlank(name)) {
|
||||||
return null;
|
return name;
|
||||||
}
|
}
|
||||||
try {
|
// 租户忽略和全局键检查
|
||||||
if (InterceptorIgnoreHelper.willIgnoreTenantLine("")) {
|
if (shouldSkipTenantProcessing() || StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
|
||||||
return super.map(name);
|
return handler.map(name);
|
||||||
}
|
|
||||||
} catch (NoClassDefFoundError ignore) {
|
|
||||||
// 有些服务不需要mp导致类不存在 忽略即可
|
|
||||||
}
|
|
||||||
if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
|
|
||||||
return super.map(name);
|
|
||||||
}
|
}
|
||||||
|
// 拼接租户前缀
|
||||||
String tenantId = TenantHelper.getTenantId();
|
String tenantId = TenantHelper.getTenantId();
|
||||||
if (StringUtils.isBlank(tenantId)) {
|
if (StringUtils.isBlank(tenantId)) {
|
||||||
log.debug("无法获取有效的租户id -> Null");
|
log.debug("无法获取有效的租户id -> Null");
|
||||||
return super.map(name);
|
return handler.map(name);
|
||||||
}
|
}
|
||||||
if (StringUtils.startsWith(name, tenantId + "")) {
|
String tenantPrefix = tenantId + ":";
|
||||||
|
if (StringUtils.startsWith(name, tenantPrefix)) {
|
||||||
// 如果存在则直接返回
|
// 如果存在则直接返回
|
||||||
return super.map(name);
|
return handler.map(name);
|
||||||
}
|
}
|
||||||
return super.map(tenantId + ":" + name);
|
return handler.map(tenantPrefix + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,30 +56,35 @@ public class TenantKeyPrefixHandler extends KeyPrefixHandler {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String unmap(String name) {
|
public String unmap(String name) {
|
||||||
String unmap = super.unmap(name);
|
String unmap = handler.unmap(name);
|
||||||
if (StringUtils.isBlank(unmap)) {
|
if (StringUtils.isBlank(unmap)) {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
if (InterceptorIgnoreHelper.willIgnoreTenantLine("")) {
|
|
||||||
return unmap;
|
|
||||||
}
|
|
||||||
} catch (NoClassDefFoundError ignore) {
|
|
||||||
// 有些服务不需要mp导致类不存在 忽略即可
|
|
||||||
}
|
|
||||||
if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
|
|
||||||
return unmap;
|
return unmap;
|
||||||
}
|
}
|
||||||
|
// 租户忽略和全局键检查
|
||||||
|
if (shouldSkipTenantProcessing() || StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
|
||||||
|
return unmap;
|
||||||
|
}
|
||||||
|
// 拼接租户前缀
|
||||||
String tenantId = TenantHelper.getTenantId();
|
String tenantId = TenantHelper.getTenantId();
|
||||||
if (StringUtils.isBlank(tenantId)) {
|
if (StringUtils.isBlank(tenantId)) {
|
||||||
log.debug("无法获取有效的租户id -> Null");
|
log.debug("无法获取有效的租户id -> Null");
|
||||||
return unmap;
|
return unmap;
|
||||||
}
|
}
|
||||||
if (StringUtils.startsWith(unmap, tenantId + "")) {
|
String tenantPrefix = tenantId + ":";
|
||||||
|
if (StringUtils.startsWith(unmap, tenantPrefix)) {
|
||||||
// 如果存在则删除
|
// 如果存在则删除
|
||||||
return unmap.substring((tenantId + ":").length());
|
return unmap.substring(tenantPrefix.length());
|
||||||
}
|
}
|
||||||
return unmap;
|
return unmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean shouldSkipTenantProcessing() {
|
||||||
|
try {
|
||||||
|
return InterceptorIgnoreHelper.willIgnoreTenantLine("");
|
||||||
|
} catch (NoClassDefFoundError ignore) {
|
||||||
|
// 有些服务不需要mp导致类不存在 忽略即可
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user