!562 优化 redisCache

pull/51/head
YunaiV 2023-08-11 21:46:44 +08:00
parent 2201a3ad0f
commit c28ef89a78
6 changed files with 73 additions and 19 deletions

View File

@ -35,7 +35,7 @@
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version> <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
<!-- 看看咋放到 bom 里 --> <!-- 看看咋放到 bom 里 -->
<lombok.version>1.18.28</lombok.version> <lombok.version>1.18.28</lombok.version>
<spring.boot.version>2.7.13</spring.boot.version> <spring.boot.version>2.7.14</spring.boot.version>
<mapstruct.version>1.5.5.Final</mapstruct.version> <mapstruct.version>1.5.5.Final</mapstruct.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>

View File

@ -16,7 +16,7 @@
<properties> <properties>
<revision>1.8.0-snapshot</revision> <revision>1.8.0-snapshot</revision>
<!-- 统一依赖管理 --> <!-- 统一依赖管理 -->
<spring.boot.version>2.7.13</spring.boot.version> <spring.boot.version>2.7.14</spring.boot.version>
<spring.cloud.version>2021.0.5</spring.cloud.version> <spring.cloud.version>2021.0.5</spring.cloud.version>
<spring.cloud.alibaba.version>2021.0.4.0</spring.cloud.alibaba.version> <spring.cloud.alibaba.version>2021.0.4.0</spring.cloud.alibaba.version>
<!-- Web 相关 --> <!-- Web 相关 -->
@ -51,7 +51,7 @@
<!-- Bpm 工作流相关 --> <!-- Bpm 工作流相关 -->
<flowable.version>6.8.0</flowable.version> <flowable.version>6.8.0</flowable.version>
<!-- 工具类相关 --> <!-- 工具类相关 -->
<captcha-plus.version>1.0.5</captcha-plus.version> <captcha-plus.version>1.0.6</captcha-plus.version>
<jsoup.version>1.15.4</jsoup.version> <jsoup.version>1.15.4</jsoup.version>
<lombok.version>1.18.28</lombok.version> <lombok.version>1.18.28</lombok.version>
<mapstruct.version>1.5.5.Final</mapstruct.version> <mapstruct.version>1.5.5.Final</mapstruct.version>

View File

@ -2,11 +2,10 @@ package cn.iocoder.yudao.framework.tenant.config;
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.yudao.framework.redis.config.YudaoCacheProperties;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnoreAspect; import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnoreAspect;
import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor; import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor;
import cn.iocoder.yudao.framework.tenant.core.job.TenantJobAspect; import cn.iocoder.yudao.framework.tenant.core.job.TenantJobAspect;
import cn.iocoder.yudao.framework.tenant.core.mq.TenantChannelInterceptor;
import cn.iocoder.yudao.framework.tenant.core.mq.TenantFunctionAroundWrapper;
import cn.iocoder.yudao.framework.tenant.core.redis.TenantRedisCacheManager; import cn.iocoder.yudao.framework.tenant.core.redis.TenantRedisCacheManager;
import cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter; import cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter;
import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService; import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService;
@ -17,24 +16,19 @@ import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
import cn.iocoder.yudao.module.system.api.tenant.TenantApi; import cn.iocoder.yudao.module.system.api.tenant.TenantApi;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import com.xxl.job.core.executor.XxlJobExecutor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
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;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.cloud.function.context.catalog.FunctionAroundWrapper;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.BatchStrategies;
import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter; import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.integration.config.GlobalChannelInterceptor;
import java.util.Objects; import java.util.Objects;
@ -104,12 +98,13 @@ public class YudaoTenantAutoConfiguration {
@Bean @Bean
@Primary // 引入租户时tenantRedisCacheManager 为主 Bean @Primary // 引入租户时tenantRedisCacheManager 为主 Bean
public RedisCacheManager tenantRedisCacheManager(RedisTemplate<String, Object> redisTemplate, public RedisCacheManager tenantRedisCacheManager(RedisTemplate<String, Object> redisTemplate,
RedisCacheConfiguration redisCacheConfiguration) { RedisCacheConfiguration redisCacheConfiguration,
YudaoCacheProperties yudaoCacheProperties) {
// 创建 RedisCacheWriter 对象 // 创建 RedisCacheWriter 对象
RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory()); RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory); RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
// 创建 TenantRedisCacheManager 对象 // 创建 TenantRedisCacheManager 对象
return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration); return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration);
} }
} }

View File

@ -23,7 +23,7 @@ import static cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguratio
* Cache Redis * Cache Redis
*/ */
@AutoConfiguration @AutoConfiguration
@EnableConfigurationProperties({CacheProperties.class}) @EnableConfigurationProperties({CacheProperties.class, YudaoCacheProperties.class})
@EnableCaching @EnableCaching
public class YudaoCacheAutoConfiguration { public class YudaoCacheAutoConfiguration {

View File

@ -0,0 +1,27 @@
package cn.iocoder.yudao.framework.redis.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;
/**
* Cache
*
* @author Wanwan
*/
@ConfigurationProperties("yudao.cache")
@Data
@Validated
public class YudaoCacheProperties {
/**
* {@link #redisScanBatchSize}
*/
private static final Integer REDIS_SCAN_BATCH_SIZE_DEFAULT = 30;
/**
* redis scan
*/
private Integer redisScanBatchSize = REDIS_SCAN_BATCH_SIZE_DEFAULT;
}

View File

@ -1,7 +1,7 @@
package cn.iocoder.yudao.framework.redis.core; package cn.iocoder.yudao.framework.redis.core;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import org.springframework.boot.convert.DurationStyle;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.cache.RedisCache; import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheConfiguration;
@ -9,12 +9,12 @@ import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter; import org.springframework.data.redis.cache.RedisCacheWriter;
import java.time.Duration; import java.time.Duration;
import java.time.temporal.ChronoUnit;
/** /**
* {@link RedisCacheManager} * {@link RedisCacheManager}
* *
* {@link Cacheable#cacheNames()} "key#ttl" # ttl * {@link Cacheable#cacheNames()} "key#ttl" # ttl
* d h m s s
* *
* @author * @author
*/ */
@ -42,10 +42,42 @@ public class TimeoutRedisCacheManager extends RedisCacheManager {
// 移除 # 后面的 : 以及后面的内容,避免影响解析 // 移除 # 后面的 : 以及后面的内容,避免影响解析
names[1] = StrUtil.subBefore(names[1], StrUtil.COLON, false); names[1] = StrUtil.subBefore(names[1], StrUtil.COLON, false);
// 解析时间 // 解析时间
Duration duration = DurationStyle.detectAndParse(names[1], ChronoUnit.SECONDS); Duration duration = parseDuration(names[1]);
cacheConfig = cacheConfig.entryTtl(duration); cacheConfig = cacheConfig.entryTtl(duration);
} }
return super.createRedisCache(names[0], cacheConfig); return super.createRedisCache(names[0], cacheConfig);
} }
/**
* Duration
*
* @param ttlStr
* @return Duration
*/
private Duration parseDuration(String ttlStr) {
String timeUnit = StrUtil.subSuf(ttlStr, -1);
switch (timeUnit) {
case "d":
return Duration.ofDays(removeDurationSuffix(ttlStr));
case "h":
return Duration.ofHours(removeDurationSuffix(ttlStr));
case "m":
return Duration.ofMinutes(removeDurationSuffix(ttlStr));
case "s":
return Duration.ofSeconds(removeDurationSuffix(ttlStr));
default:
return Duration.ofSeconds(Long.parseLong(ttlStr));
}
}
/**
*
*
* @param ttlStr
* @return
*/
private Long removeDurationSuffix(String ttlStr) {
return NumberUtil.parseLong(StrUtil.sub(ttlStr, 0, ttlStr.length() - 1));
}
} }