Commit 8960a8297839d79e7f418f0618bf8cd0b77ac524

Authored by 芋道源码
Committed by Gitee
2 parents b5515799 134e5ca2

!562 优化 redisCache

Merge pull request !562 from wanwan/feature/redis_cache_optimize_20230810
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
... ... @@ -4,6 +4,7 @@ import cn.hutool.core.annotation.AnnotationUtil;
4 4 import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
5 5 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
6 6 import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
  7 +import cn.iocoder.yudao.framework.redis.config.YudaoCacheProperties;
7 8 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnoreAspect;
8 9 import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor;
9 10 import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
... ... @@ -27,6 +28,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
27 28 import org.springframework.boot.web.servlet.FilterRegistrationBean;
28 29 import org.springframework.context.annotation.Bean;
29 30 import org.springframework.context.annotation.Primary;
  31 +import org.springframework.data.redis.cache.BatchStrategies;
30 32 import org.springframework.data.redis.cache.RedisCacheConfiguration;
31 33 import org.springframework.data.redis.cache.RedisCacheManager;
32 34 import org.springframework.data.redis.cache.RedisCacheWriter;
... ... @@ -124,10 +126,12 @@ public class YudaoTenantAutoConfiguration {
124 126 @Bean
125 127 @Primary // 引入租户时,tenantRedisCacheManager 为主 Bean
126 128 public RedisCacheManager tenantRedisCacheManager(RedisTemplate<String, Object> redisTemplate,
127   - RedisCacheConfiguration redisCacheConfiguration) {
  129 + RedisCacheConfiguration redisCacheConfiguration,
  130 + YudaoCacheProperties yudaoCacheProperties) {
128 131 // 创建 RedisCacheWriter 对象
129 132 RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
130   - RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
  133 + RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
  134 + BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
131 135 // 创建 TenantRedisCacheManager 对象
132 136 return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration);
133 137 }
... ...
yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
... ... @@ -8,6 +8,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
8 8 import org.springframework.cache.annotation.EnableCaching;
9 9 import org.springframework.context.annotation.Bean;
10 10 import org.springframework.context.annotation.Primary;
  11 +import org.springframework.data.redis.cache.BatchStrategies;
11 12 import org.springframework.data.redis.cache.RedisCacheConfiguration;
12 13 import org.springframework.data.redis.cache.RedisCacheManager;
13 14 import org.springframework.data.redis.cache.RedisCacheWriter;
... ... @@ -23,7 +24,7 @@ import static cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguratio
23 24 * Cache 配置类,基于 Redis 实现
24 25 */
25 26 @AutoConfiguration
26   -@EnableConfigurationProperties({CacheProperties.class})
  27 +@EnableConfigurationProperties({CacheProperties.class, YudaoCacheProperties.class})
27 28 @EnableCaching
28 29 public class YudaoCacheAutoConfiguration {
29 30  
... ... @@ -62,10 +63,12 @@ public class YudaoCacheAutoConfiguration {
62 63  
63 64 @Bean
64 65 public RedisCacheManager redisCacheManager(RedisTemplate<String, Object> redisTemplate,
65   - RedisCacheConfiguration redisCacheConfiguration) {
  66 + RedisCacheConfiguration redisCacheConfiguration,
  67 + YudaoCacheProperties yudaoCacheProperties) {
66 68 // 创建 RedisCacheWriter 对象
67 69 RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
68   - RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
  70 + RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
  71 + BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
69 72 // 创建 TenantRedisCacheManager 对象
70 73 return new TimeoutRedisCacheManager(cacheWriter, redisCacheConfiguration);
71 74 }
... ...
yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.redis.config;
  2 +
  3 +import lombok.Data;
  4 +import org.springframework.boot.context.properties.ConfigurationProperties;
  5 +import org.springframework.validation.annotation.Validated;
  6 +
  7 +/**
  8 + * Cache 配置项
  9 + *
  10 + * @author
  11 + */
  12 +@ConfigurationProperties("yudao.cache")
  13 +@Data
  14 +@Validated
  15 +public class YudaoCacheProperties {
  16 +
  17 + /**
  18 + * redis scan 一次返回数量
  19 + */
  20 + private Integer redisScanBatchSize = 30;
  21 +}
... ...
yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java
1 1 package cn.iocoder.yudao.framework.redis.core;
2 2  
  3 +import cn.hutool.core.util.NumberUtil;
3 4 import cn.hutool.core.util.StrUtil;
4 5 import org.springframework.boot.convert.DurationStyle;
5 6 import org.springframework.cache.annotation.Cacheable;
... ... @@ -13,8 +14,8 @@ import java.time.temporal.ChronoUnit;
13 14  
14 15 /**
15 16 * 支持自定义过期时间的 {@link RedisCacheManager} 实现类
16   - *
17   - * 在 {@link Cacheable#cacheNames()} 格式为 "key#ttl" 时,# 后面的 ttl 为过期时间,单位为秒
  17 + * <p>
  18 + * 在 {@link Cacheable#cacheNames()} 格式为 "key#ttl" 时,# 后面的 ttl 为过期时间,单位为最后一个字母(支持的单位有:d天,h小时,m分钟,s秒),默认单位为秒
18 19 *
19 20 * @author 芋道源码
20 21 */
... ... @@ -42,10 +43,41 @@ public class TimeoutRedisCacheManager extends RedisCacheManager {
42 43 // 移除 # 后面的 : 以及后面的内容,避免影响解析
43 44 names[1] = StrUtil.subBefore(names[1], StrUtil.COLON, false);
44 45 // 解析时间
45   - Duration duration = DurationStyle.detectAndParse(names[1], ChronoUnit.SECONDS);
  46 + Duration duration = parseDuration(names[1]);
46 47 cacheConfig = cacheConfig.entryTtl(duration);
47 48 }
48 49 return super.createRedisCache(names[0], cacheConfig);
49 50 }
50 51  
  52 + /**
  53 + * 解析 Duration
  54 + *
  55 + * @param ttlStr
  56 + * @return
  57 + */
  58 + private Duration parseDuration(String ttlStr) {
  59 + String timeUnit = StrUtil.subSuf(ttlStr, -1);
  60 + switch (timeUnit) {
  61 + case "d":
  62 + return Duration.ofDays(removeSuffix(ttlStr));
  63 + case "h":
  64 + return Duration.ofHours(removeSuffix(ttlStr));
  65 + case "m":
  66 + return Duration.ofMinutes(removeSuffix(ttlStr));
  67 + case "s":
  68 + return Duration.ofSeconds(removeSuffix(ttlStr));
  69 + default:
  70 + return Duration.ofSeconds(Long.parseLong(ttlStr));
  71 + }
  72 + }
  73 +
  74 + /**
  75 + * 移除多余的后缀
  76 + *
  77 + * @param ttlStr
  78 + * @return
  79 + */
  80 + private Long removeSuffix(String ttlStr) {
  81 + return NumberUtil.parseLong(StrUtil.sub(ttlStr, 0, ttlStr.length() - 1));
  82 + }
51 83 }
... ...
yudao-server/src/main/resources/application.yaml
... ... @@ -204,6 +204,8 @@ yudao:
204 204 order:
205 205 app-id: 1 # 商户编号
206 206 expire-time: 2h # 支付的过期时间
  207 + cache: # spring cache 相关配置
  208 + redis-scan-batch-size: 30 # redis scan 一次返回数量
207 209  
208 210 debug: false
209 211  
... ...