From b48206dc809ac610c37e97ba9328bee6c9138e74 Mon Sep 17 00:00:00 2001 From: D <3066417822@qq.com> Date: Wed, 24 Apr 2024 14:22:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=89=A5=E7=A6=BBredis=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- ruoyi-admin/pom.xml | 2 +- .../controller/monitor/CacheController.java | 31 --------- .../main/resources/application-middleware.yml | 31 +++++++++ .../src/main/resources/application-minio.yml | 6 -- .../src/main/resources/application.yml | 27 +------- ruoyi-common/pom.xml | 6 -- .../common/core/cache/CacheSpecialUtils.java | 14 ++++ .../com/ruoyi/common/utils/CacheUtils.java | 60 +++-------------- .../framework/config/Ehcache3Config.java | 55 +++++++++++++-- ruoyi-middleware/pom.xml | 15 +++-- .../minio/utils/FileUploadMinioUtils.java | 1 - .../ruoyi-middleware-redis/pom.xml | 33 +++++++++ .../redis}/aspectj/RateLimiterAspect.java | 2 +- .../config/FastJson2JsonRedisSerializer.java | 2 +- .../middleware/redis}/config/RedisConfig.java | 60 ++++++++++++----- .../controller/RedisCacheController.java | 64 ++++++++++++++++++ .../middleware/redis/utils}/RedisCache.java | 5 +- .../ruoyi-middleware-starter/pom.xml | 5 ++ ruoyi-oauth/pom.xml | 8 --- .../phone/service/Impl/DySmsServiceImpl.java | 67 +++++++++---------- ruoyi-pay/pom.xml | 7 -- 22 files changed, 302 insertions(+), 201 deletions(-) create mode 100644 ruoyi-admin/src/main/resources/application-middleware.yml delete mode 100644 ruoyi-admin/src/main/resources/application-minio.yml create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/cache/CacheSpecialUtils.java create mode 100644 ruoyi-middleware/ruoyi-middleware-redis/pom.xml rename {ruoyi-framework/src/main/java/com/ruoyi/framework => ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis}/aspectj/RateLimiterAspect.java (98%) rename {ruoyi-framework/src/main/java/com/ruoyi/framework => ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis}/config/FastJson2JsonRedisSerializer.java (97%) rename {ruoyi-framework/src/main/java/com/ruoyi/framework => ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis}/config/RedisConfig.java (69%) create mode 100644 ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis/controller/RedisCacheController.java rename {ruoyi-common/src/main/java/com/ruoyi/common/core/redis => ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis/utils}/RedisCache.java (96%) diff --git a/pom.xml b/pom.xml index b38a90c..206dedd 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ UTF-8 17 3.1.1 - 3.2.4 + 3.2.5 1.2.21 4.1.1 3.5.2 diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index b1a6ba1..e58c1e1 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -71,7 +71,7 @@ ruoyi-mybatis-jpa - + com.ruoyi ruoyi-middleware-starter diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java index 0e6dab9..969e421 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java @@ -1,15 +1,10 @@ package com.ruoyi.web.controller.monitor; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.Properties; import java.util.Set; import org.springframework.cache.Cache.ValueWrapper; -import org.springframework.data.redis.cache.RedisCacheManager; -import org.springframework.data.redis.core.RedisCallback; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -52,32 +47,6 @@ public class CacheController caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数")); } - @Operation(summary = "获取缓存信息") - @PreAuthorize("@ss.hasPermi('monitor:cache:list')") - @GetMapping() - public AjaxResult getInfo() throws Exception - { - Map result = new HashMap<>(3); - if (CacheUtils.getCacheManager() instanceof RedisCacheManager) - { - Properties info = (Properties) CacheUtils.getRedisTemplate().execute((RedisCallback) connection -> connection.info()); - Properties commandStats = (Properties) CacheUtils.getRedisTemplate().execute((RedisCallback) connection -> connection.info("commandstats")); - Object dbSize = CacheUtils.getRedisTemplate().execute((RedisCallback) connection -> connection.dbSize()); - result.put("info", info); - result.put("dbSize", dbSize); - - List> pieList = new ArrayList<>(); - commandStats.stringPropertyNames().forEach(key -> { - Map data = new HashMap<>(2); - String property = commandStats.getProperty(key); - data.put("name", StringUtils.removeStart(key, "cmdstat_")); - data.put("value", StringUtils.substringBetween(property, "calls=", ",usec")); - pieList.add(data); - }); - result.put("commandStats", pieList); - } - return AjaxResult.success(result); - } @Operation(summary = "获取缓存名列表") @PreAuthorize("@ss.hasPermi('monitor:cache:list')") diff --git a/ruoyi-admin/src/main/resources/application-middleware.yml b/ruoyi-admin/src/main/resources/application-middleware.yml new file mode 100644 index 0000000..118ed25 --- /dev/null +++ b/ruoyi-admin/src/main/resources/application-middleware.yml @@ -0,0 +1,31 @@ +spring: + data: + # redis 配置 + redis: + # 地址 + host: localhost + # 端口,默认为6379 + port: 6379 + # 数据库索引 + database: 0 + # 密码 + password: + # 连接超时时间 + timeout: 10s + lettuce: + pool: + # 连接池中的最小空闲连接 + min-idle: 0 + # 连接池中的最大空闲连接 + max-idle: 8 + # 连接池的最大数据库连接数 + max-active: 8 + # #连接池最大阻塞等待时间(使用负值表示没有限制) + max-wait: -1ms + +# Minio配置 +minio: + url: http://localhost:9000 + accessKey: minioadmin + secretKey: minioadmin + bucketName: ruoyi diff --git a/ruoyi-admin/src/main/resources/application-minio.yml b/ruoyi-admin/src/main/resources/application-minio.yml deleted file mode 100644 index 1fcd6a3..0000000 --- a/ruoyi-admin/src/main/resources/application-minio.yml +++ /dev/null @@ -1,6 +0,0 @@ -# Minio配置 -minio: - url: http://localhost:9000 - accessKey: minioadmin - secretKey: minioadmin - bucketName: ruoyi \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index cee266f..0740eda 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -49,7 +49,7 @@ user: spring: cache: # 指定缓存类型 jcache 本地缓存 redis 缓存 - type: jcache + type: redis redis: # 指定存活时间(ms) time-to-live: 86400000 @@ -65,7 +65,7 @@ spring: # 国际化资源文件路径 basename: i18n/messages profiles: - active: druid,mybatis,oauth,pay,minio + active: druid,mybatis,oauth,pay,middleware # 文件上传 servlet: multipart: @@ -78,29 +78,6 @@ spring: restart: # 热部署开关 enabled: true - data: - # redis 配置 - redis: - # 地址 - host: localhost - # 端口,默认为6379 - port: 6379 - # 数据库索引 - database: 0 - # 密码 - password: - # 连接超时时间 - timeout: 10s - lettuce: - pool: - # 连接池中的最小空闲连接 - min-idle: 0 - # 连接池中的最大空闲连接 - max-idle: 8 - # 连接池的最大数据库连接数 - max-active: 8 - # #连接池最大阻塞等待时间(使用负值表示没有限制) - max-wait: -1ms # token配置 token: diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index 0e16728..7ed8287 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -111,12 +111,6 @@ 2.3.0.1 - - - org.springframework.boot - spring-boot-starter-data-redis - - org.apache.commons diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/cache/CacheSpecialUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/cache/CacheSpecialUtils.java new file mode 100644 index 0000000..90ea1b9 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/cache/CacheSpecialUtils.java @@ -0,0 +1,14 @@ +package com.ruoyi.common.core.cache; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.springframework.cache.Cache; + +public interface CacheSpecialUtils { + public Set getKeys(Cache cache); + + default public void set(String string, T value, long timeout, TimeUnit unit){} + + default public void set(String string, T value){}; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/CacheUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/CacheUtils.java index f995465..1d7eb25 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/CacheUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/CacheUtils.java @@ -1,34 +1,19 @@ package com.ruoyi.common.utils; -import java.lang.reflect.Field; -import java.util.HashSet; import java.util.Set; import java.util.concurrent.TimeUnit; -import org.ehcache.core.EhcacheBase; -import org.ehcache.impl.internal.concurrent.ConcurrentHashMap; -import org.ehcache.impl.internal.store.heap.OnHeapStore; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.cache.jcache.JCacheCache; import org.springframework.cache.transaction.TransactionAwareCacheDecorator; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; +import com.ruoyi.common.core.cache.CacheSpecialUtils; import com.ruoyi.common.utils.spring.SpringUtils; public class CacheUtils { - /** - * 使用redis时对redis进行单独特殊操作需要使用 - * - * @param - * @param - * @return - */ - public static RedisTemplate getRedisTemplate() { - return SpringUtils.getBean("redisTemplate"); - } /** * 获取CacheManager @@ -58,38 +43,8 @@ public class CacheUtils { @SuppressWarnings(value = { "unchecked", "rawtypes" }) public static Set getkeys(String cacheName) { Cache cache = getCacheManager().getCache(cacheName); - Set keyset = new HashSet<>(); - if (cache instanceof JCacheCache) { - try { - JCacheCache jehcache = (JCacheCache) cache; - // org.ehcache.jsr107.Eh107Cache 不公开 - Object nativeCache = jehcache.getNativeCache(); - Class nativeCacheClass = nativeCache.getClass(); - Field ehCacheField = nativeCacheClass.getDeclaredField("ehCache"); - ehCacheField.setAccessible(true); - EhcacheBase ehcache = (EhcacheBase) ehCacheField.get(nativeCache); - Field storeField = EhcacheBase.class.getDeclaredField("store"); - storeField.setAccessible(true); - OnHeapStore store = (OnHeapStore) storeField.get(ehcache); - Field mapField = OnHeapStore.class.getDeclaredField("map"); - mapField.setAccessible(true); - // org.ehcache.impl.internal.store.heap.Backend 不公开 - Object map = mapField.get(store); - Class mapClass = map.getClass(); - Field realMapField = mapClass.getDeclaredField("realMap"); - realMapField.setAccessible(true); - ConcurrentHashMap realMap = (ConcurrentHashMap) realMapField.get(map); - keyset = realMap.keySet(); - } catch (Exception e) { - } - - } else if (cache instanceof TransactionAwareCacheDecorator) { - Set keysets = getRedisTemplate().keys(cache.getName() + "*"); - for (Object s : keysets) { - keyset.add(StringUtils.replace(s.toString(), cache.getName() + ":", "")); - } - } - return keyset; + CacheSpecialUtils cacheGetKets = SpringUtils.getBean(CacheSpecialUtils.class); + return cacheGetKets.getKeys(cache); } /** @@ -118,6 +73,10 @@ public class CacheUtils { } } + public static boolean hasKey(String cacheName, String key){ + return ObjectUtils.isEmpty(get(cacheName, key)); + } + /** * 根据cacheName,key和缓存过期时间进行缓存数据,使用各种不同缓存可以单独进行操作 * @@ -134,10 +93,11 @@ public class CacheUtils { JCacheCache ehcache = (JCacheCache) cache; ehcache.put(key, value); } else if (cache instanceof TransactionAwareCacheDecorator) { + CacheSpecialUtils cacheSet = SpringUtils.getBean(CacheSpecialUtils.class); if (timeout != 0 && unit != null) { - getRedisTemplate().opsForValue().set(cacheName + ":" + key, value, timeout, unit); + cacheSet.set(cacheName + ":" + key, value, timeout, unit); } else { - getRedisTemplate().opsForValue().set(cacheName + ":" + key, value); + cacheSet.set(cacheName + ":" + key, value); } } else { cache.put(key, value); diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/Ehcache3Config.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/Ehcache3Config.java index e9fd659..7e66346 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/Ehcache3Config.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/Ehcache3Config.java @@ -1,5 +1,8 @@ package com.ruoyi.framework.config; +import java.lang.reflect.Field; +import java.util.HashSet; +import java.util.Set; import java.util.concurrent.TimeUnit; import javax.cache.CacheManager; @@ -8,19 +11,61 @@ import javax.cache.configuration.MutableConfiguration; import javax.cache.expiry.CreatedExpiryPolicy; import javax.cache.expiry.Duration; +import org.ehcache.core.EhcacheBase; +import org.ehcache.impl.internal.concurrent.ConcurrentHashMap; +import org.ehcache.impl.internal.store.heap.OnHeapStore; import org.ehcache.jsr107.EhcacheCachingProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cache.Cache; import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.jcache.JCacheCache; +import org.springframework.cache.jcache.JCacheCacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import com.ruoyi.common.core.cache.CacheSpecialUtils; + @Configuration @EnableCaching @ConditionalOnProperty(prefix = "spring.cache", name = { "type" }, havingValue = "jcache", matchIfMissing = false) public class Ehcache3Config { @Bean - public CacheManager ehcacheManager() { + @SuppressWarnings(value = { "unchecked", "rawtypes" }) + public CacheSpecialUtils cacheGetKets() { + return new CacheSpecialUtils() { + @Override + public Set getKeys(Cache cache) { + Set keyset = new HashSet<>(); + try { + JCacheCache jehcache = (JCacheCache) cache; + // org.ehcache.jsr107.Eh107Cache 不公开 + Object nativeCache = jehcache.getNativeCache(); + Class nativeCacheClass = nativeCache.getClass(); + Field ehCacheField = nativeCacheClass.getDeclaredField("ehCache"); + ehCacheField.setAccessible(true); + EhcacheBase ehcache = (EhcacheBase) ehCacheField.get(nativeCache); + Field storeField = EhcacheBase.class.getDeclaredField("store"); + storeField.setAccessible(true); + OnHeapStore store = (OnHeapStore) storeField.get(ehcache); + Field mapField = OnHeapStore.class.getDeclaredField("map"); + mapField.setAccessible(true); + // org.ehcache.impl.internal.store.heap.Backend 不公开 + Object map = mapField.get(store); + Class mapClass = map.getClass(); + Field realMapField = mapClass.getDeclaredField("realMap"); + realMapField.setAccessible(true); + ConcurrentHashMap realMap = (ConcurrentHashMap) realMapField.get(map); + keyset = realMap.keySet(); + } catch (Exception e) { + } + return keyset; + } + }; + } + + @Bean + public JCacheCacheManager ehcacheManager() { EhcacheCachingProvider cachingProvider = (EhcacheCachingProvider) Caching.getCachingProvider(); CacheManager cacheManager = (CacheManager) cachingProvider.getCacheManager(); @@ -30,7 +75,7 @@ public class Ehcache3Config { mutableConfiguration.setManagementEnabled(true); // 启用管理功能(可选) mutableConfiguration.setStatisticsEnabled(true); // 启用统计功能(可选) // 设置缓存过期策略(以 timeToIdle 为例,根据实际需求调整) - mutableConfiguration.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.HOURS,1))); + mutableConfiguration.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.HOURS, 1))); cacheManager.createCache("temp_cache", mutableConfiguration); cacheManager.createCache("eternal_cache", mutableConfiguration); @@ -41,8 +86,10 @@ public class Ehcache3Config { cacheManager.createCache("login_tokens", mutableConfiguration); cacheManager.createCache("rate_limit", mutableConfiguration); cacheManager.createCache("pwd_err_cnt", mutableConfiguration); - - return cacheManager; + + JCacheCacheManager jCacheCacheManager = new JCacheCacheManager(cacheManager); + + return jCacheCacheManager; } } diff --git a/ruoyi-middleware/pom.xml b/ruoyi-middleware/pom.xml index f9aef1c..0a9cae9 100644 --- a/ruoyi-middleware/pom.xml +++ b/ruoyi-middleware/pom.xml @@ -13,6 +13,7 @@ 3.8.7.3.2 8.2.1 + 3.2.5 @@ -20,13 +21,6 @@ - - - com.ruoyi - ruoyi-common - ${ruoyi.version} - - io.minio @@ -40,6 +34,12 @@ ${ruoyi.version} + + com.ruoyi + ruoyi-middleware-redis + ${ruoyi.version} + + com.ruoyi ruoyi-middleware-starter @@ -51,6 +51,7 @@ ruoyi-middleware-minio + ruoyi-middleware-redis ruoyi-middleware-starter pom diff --git a/ruoyi-middleware/ruoyi-middleware-minio/src/main/java/com/ruoyi/middleware/minio/utils/FileUploadMinioUtils.java b/ruoyi-middleware/ruoyi-middleware-minio/src/main/java/com/ruoyi/middleware/minio/utils/FileUploadMinioUtils.java index c68294b..07530af 100644 --- a/ruoyi-middleware/ruoyi-middleware-minio/src/main/java/com/ruoyi/middleware/minio/utils/FileUploadMinioUtils.java +++ b/ruoyi-middleware/ruoyi-middleware-minio/src/main/java/com/ruoyi/middleware/minio/utils/FileUploadMinioUtils.java @@ -10,7 +10,6 @@ import com.ruoyi.common.exception.file.InvalidExtensionException; import com.ruoyi.common.utils.file.FileUploadUtils; import com.ruoyi.common.utils.file.MimeTypeUtils; import com.ruoyi.middleware.minio.config.MinioConfig; -import com.ruoyi.middleware.minio.utils.MinioUtil; public class FileUploadMinioUtils extends FileUploadUtils { /** diff --git a/ruoyi-middleware/ruoyi-middleware-redis/pom.xml b/ruoyi-middleware/ruoyi-middleware-redis/pom.xml new file mode 100644 index 0000000..c02ffdf --- /dev/null +++ b/ruoyi-middleware/ruoyi-middleware-redis/pom.xml @@ -0,0 +1,33 @@ + + + + ruoyi-middleware + com.ruoyi + 3.8.7.3.2 + + 4.0.0 + + ruoyi-middleware-redis + + + 中间件 + + + + + + + com.ruoyi + ruoyi-common + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java b/ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis/aspectj/RateLimiterAspect.java similarity index 98% rename from ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java rename to ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis/aspectj/RateLimiterAspect.java index f5e24d1..f4342f1 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RateLimiterAspect.java +++ b/ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis/aspectj/RateLimiterAspect.java @@ -1,4 +1,4 @@ -package com.ruoyi.framework.aspectj; +package com.ruoyi.middleware.redis.aspectj; import java.lang.reflect.Method; import java.util.Collections; diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java b/ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis/config/FastJson2JsonRedisSerializer.java similarity index 97% rename from ruoyi-framework/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java rename to ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis/config/FastJson2JsonRedisSerializer.java index 2be510f..bbc9fdf 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/FastJson2JsonRedisSerializer.java +++ b/ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis/config/FastJson2JsonRedisSerializer.java @@ -1,4 +1,4 @@ -package com.ruoyi.framework.config; +package com.ruoyi.middleware.redis.config; import java.nio.charset.Charset; diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java b/ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis/config/RedisConfig.java similarity index 69% rename from ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java rename to ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis/config/RedisConfig.java index a214ca9..f4f92fa 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/RedisConfig.java +++ b/ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis/config/RedisConfig.java @@ -1,8 +1,12 @@ -package com.ruoyi.framework.config; +package com.ruoyi.middleware.redis.config; import java.time.Duration; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.TimeUnit; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurer; import org.springframework.context.annotation.Bean; @@ -16,6 +20,9 @@ import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.StringRedisSerializer; +import com.ruoyi.common.core.cache.CacheSpecialUtils; +import com.ruoyi.common.utils.StringUtils; + /** * redis配置 * @@ -23,40 +30,61 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; */ @Configuration @ConditionalOnProperty(prefix = "spring.cache", name = { "type" }, havingValue = "redis", matchIfMissing = false) -public class RedisConfig implements CachingConfigurer -{ +public class RedisConfig implements CachingConfigurer { @Bean @Primary - public CacheManager cacheManager(RedisConnectionFactory connectionFactory) - { + public CacheManager cacheManager(RedisConnectionFactory connectionFactory) { RedisCacheConfiguration config = instanceConfig(3600 * 24 * 15L); return RedisCacheManager.builder(connectionFactory).cacheDefaults(config).transactionAware().build(); } @Bean - public CacheManager cacheManager30m(RedisConnectionFactory connectionFactory) - { + public CacheManager cacheManager30m(RedisConnectionFactory connectionFactory) { RedisCacheConfiguration config = instanceConfig(1800L); return RedisCacheManager.builder(connectionFactory).cacheDefaults(config).transactionAware().build(); } + @Bean + public CacheSpecialUtils cacheGetKets(RedisTemplate redisTemplate) { + return new CacheSpecialUtils() { + @Override + public Set getKeys(Cache cache) { + Set keyset = new HashSet<>(); + Set keysets = redisTemplate.keys(cache.getName() + "*"); + for (Object s : keysets) { + keyset.add(StringUtils.replace(s.toString(), cache.getName() + ":", "")); + } + return keyset; + } + + @Override + public void set(String cacheName, T value, long timeout, TimeUnit unit){ + redisTemplate.opsForValue().set(cacheName, value, timeout, unit); + } + + public void set(String cacheName, T value){ + redisTemplate.opsForValue().set(cacheName, value); + }; + + }; + } + @SuppressWarnings(value = { "unchecked", "rawtypes" }) - private RedisCacheConfiguration instanceConfig(Long ttl) - { + private RedisCacheConfiguration instanceConfig(Long ttl) { FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); return RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(ttl)).disableCachingNullValues() .computePrefixWith(name -> name + ":") - .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) + .serializeKeysWith( + RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer)); } @Bean @SuppressWarnings(value = { "unchecked", "rawtypes" }) - public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) - { + public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); - + FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); // 使用StringRedisSerializer来序列化和反序列化redis的key值 @@ -72,8 +100,7 @@ public class RedisConfig implements CachingConfigurer } @Bean - public DefaultRedisScript limitScript() - { + public DefaultRedisScript limitScript() { DefaultRedisScript redisScript = new DefaultRedisScript<>(); redisScript.setScriptText(limitScriptText()); redisScript.setResultType(Long.class); @@ -83,8 +110,7 @@ public class RedisConfig implements CachingConfigurer /** * 限流脚本 */ - private String limitScriptText() - { + private String limitScriptText() { return "local key = KEYS[1]\n" + "local count = tonumber(ARGV[1])\n" + "local time = tonumber(ARGV[2])\n" + diff --git a/ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis/controller/RedisCacheController.java b/ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis/controller/RedisCacheController.java new file mode 100644 index 0000000..00a49d1 --- /dev/null +++ b/ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis/controller/RedisCacheController.java @@ -0,0 +1,64 @@ +package com.ruoyi.middleware.redis.controller; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.data.redis.core.RedisCallback; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.utils.StringUtils; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; + +/** + * 缓存监控 + * + * @author ruoyi + */ +@Tag(name = "缓存监控") +@RestController +@SuppressWarnings(value = { "unchecked", "rawtypes" }) +@ConditionalOnProperty(prefix = "spring.cache", name = { "type" }, havingValue = "redis", matchIfMissing = false) +@RequestMapping("/monitor/cache") +public class RedisCacheController { + @Autowired + private RedisTemplate redisTemplate; + + @Operation(summary = "获取缓存信息") + @PreAuthorize("@ss.hasPermi('monitor:cache:list')") + @GetMapping() + public AjaxResult getInfo() throws Exception { + Map result = new HashMap<>(3); + + Properties info = (Properties) redisTemplate + .execute((RedisCallback) connection -> connection.commands().info()); + Properties commandStats = (Properties) redisTemplate + .execute((RedisCallback) connection -> connection.commands().info("commandstats")); + Object dbSize = redisTemplate.execute((RedisCallback) connection -> connection.commands().dbSize()); + result.put("info", info); + result.put("dbSize", dbSize); + + List> pieList = new ArrayList<>(); + commandStats.stringPropertyNames().forEach(key -> { + Map data = new HashMap<>(2); + String property = commandStats.getProperty(key); + data.put("name", StringUtils.removeStart(key, "cmdstat_")); + data.put("value", StringUtils.substringBetween(property, "calls=", ",usec")); + pieList.add(data); + }); + result.put("commandStats", pieList); + return AjaxResult.success(result); + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java b/ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis/utils/RedisCache.java similarity index 96% rename from ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java rename to ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis/utils/RedisCache.java index 44e80d8..d4c1050 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java +++ b/ruoyi-middleware/ruoyi-middleware-redis/src/main/java/com/ruoyi/middleware/redis/utils/RedisCache.java @@ -1,4 +1,4 @@ -package com.ruoyi.common.core.redis; +package com.ruoyi.middleware.redis.utils; import java.util.Collection; import java.util.Iterator; @@ -6,7 +6,9 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; + import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.data.redis.core.BoundSetOperations; import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.RedisTemplate; @@ -20,6 +22,7 @@ import org.springframework.stereotype.Component; **/ @SuppressWarnings(value = { "unchecked", "rawtypes" }) @Component +@ConditionalOnProperty(prefix = "spring.cache", name = { "type" }, havingValue = "redis", matchIfMissing = false) public class RedisCache { @Autowired diff --git a/ruoyi-middleware/ruoyi-middleware-starter/pom.xml b/ruoyi-middleware/ruoyi-middleware-starter/pom.xml index 2adf51f..93f74fa 100644 --- a/ruoyi-middleware/ruoyi-middleware-starter/pom.xml +++ b/ruoyi-middleware/ruoyi-middleware-starter/pom.xml @@ -27,6 +27,11 @@ ruoyi-middleware-minio + + com.ruoyi + ruoyi-middleware-redis + + diff --git a/ruoyi-oauth/pom.xml b/ruoyi-oauth/pom.xml index 2d715d4..29a7e42 100644 --- a/ruoyi-oauth/pom.xml +++ b/ruoyi-oauth/pom.xml @@ -20,14 +20,6 @@ - - - - com.ruoyi - ruoyi-framework - ${ruoyi.version} - - com.ruoyi diff --git a/ruoyi-oauth/ruoyi-oauth-phone/src/main/java/com/ruoyi/oauth/phone/service/Impl/DySmsServiceImpl.java b/ruoyi-oauth/ruoyi-oauth-phone/src/main/java/com/ruoyi/oauth/phone/service/Impl/DySmsServiceImpl.java index 76ce849..7b4ed65 100644 --- a/ruoyi-oauth/ruoyi-oauth-phone/src/main/java/com/ruoyi/oauth/phone/service/Impl/DySmsServiceImpl.java +++ b/ruoyi-oauth/ruoyi-oauth-phone/src/main/java/com/ruoyi/oauth/phone/service/Impl/DySmsServiceImpl.java @@ -11,8 +11,8 @@ import org.springframework.stereotype.Service; import com.alibaba.fastjson2.JSONObject; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.CacheUtils; import com.ruoyi.framework.web.service.TokenService; import com.ruoyi.framework.web.service.UserDetailsServiceImpl; import com.ruoyi.oauth.common.enums.OauthVerificationUse; @@ -34,32 +34,32 @@ public class DySmsServiceImpl implements DySmsService, OauthVerificationCodeServ @Autowired private DySmsUtil dySmsUtil; @Autowired - private RedisCache redisCache; - @Autowired private ISysUserService userService; @Autowired private UserDetailsServiceImpl userDetailsServiceImpl; @Autowired private TokenService tokenService; + private static final String CACHE_NAME = "phone_codes"; + private static final Logger log = LoggerFactory.getLogger(DySmsServiceImpl.class); - - public boolean beforeSendCode(String phone, OauthVerificationUse use) throws Exception {//1.查验手机号是否存在,分辨登录和删除用户以及注册用户 - boolean havePhoneFlag= userService.selectUserByPhone(phone) != null; - if((use.equals(OauthVerificationUse.LOGIN ) || use.equals(OauthVerificationUse.DISABLE )||use.equals(OauthVerificationUse.RESET_PASSWORD) )&& !havePhoneFlag){ - throw new ServiceException("该手机号未绑定用户"); - }else if((use.equals(OauthVerificationUse.REGISTER ) ||use.equals(OauthVerificationUse.RESET_PHONE))&& havePhoneFlag){ - throw new ServiceException("该手机号已绑定用户"); - } - return true; + public boolean beforeSendCode(String phone, OauthVerificationUse use) throws Exception {// 1.查验手机号是否存在,分辨登录和删除用户以及注册用户 + boolean havePhoneFlag = userService.selectUserByPhone(phone) != null; + if ((use.equals(OauthVerificationUse.LOGIN) || use.equals(OauthVerificationUse.DISABLE) + || use.equals(OauthVerificationUse.RESET_PASSWORD)) && !havePhoneFlag) { + throw new ServiceException("该手机号未绑定用户"); + } else if ((use.equals(OauthVerificationUse.REGISTER) || use.equals(OauthVerificationUse.RESET_PHONE)) + && havePhoneFlag) { + throw new ServiceException("该手机号已绑定用户"); + } + return true; } @Override - public boolean sendCode(String phone, String code, OauthVerificationUse use) throws Exception {//1.查验手机号是否存在,分辨登录和删除用户以及注册用户 - //限制短信一分钟只能发送一次短信 - String cacheKey = "phone_codes_" + use.getValue() + "_" + phone; - if(redisCache.hasKey(cacheKey)){ + public boolean sendCode(String phone, String code, OauthVerificationUse use) throws Exception {// 1.查验手机号是否存在,分辨登录和删除用户以及注册用户 + // 限制短信一分钟只能发送一次短信 + if (CacheUtils.hasKey(CACHE_NAME, phone + use.getValue())) { throw new ServiceException("请在1分钟后再发送短信"); } @@ -67,7 +67,7 @@ public class DySmsServiceImpl implements DySmsService, OauthVerificationCodeServ JSONObject templateParams = new JSONObject(); templateParams.put("code", code); dySmsUtil.sendSms(DySmsTemplate.Test_TEMPLATE_CODE, templateParams, phone); - redisCache.setCacheObject("phone_codes_" + use.getValue() + "_" + phone, code, 1, TimeUnit.MINUTES); + CacheUtils.put(CACHE_NAME, phone + use.getValue(), code, 1, TimeUnit.MINUTES); log.info("发送手机验证码成功:{ phone: " + phone + " code:" + code + "}"); return true; } catch (Exception e) { @@ -76,40 +76,38 @@ public class DySmsServiceImpl implements DySmsService, OauthVerificationCodeServ } } - @Override - public String checkCode(String phone, String code, OauthVerificationUse use) throws Exception{ - String cacheKey = "phone_codes_" + use.getValue() + "_" + phone; - String cachedCode = redisCache.getCacheObject(cacheKey); // 从缓存中获取验证码 - boolean havePhoneFlag= userService.selectUserByPhone(phone) != null; - if(use.equals(OauthVerificationUse.LOGIN ) && havePhoneFlag){//登录校验 + public String checkCode(String phone, String code, OauthVerificationUse use) throws Exception { + String cachedCode = CacheUtils.get(use.getValue(), use.getValue() + phone, String.class); // 从缓存中获取验证码 + boolean havePhoneFlag = userService.selectUserByPhone(phone) != null; + if (use.equals(OauthVerificationUse.LOGIN) && havePhoneFlag) {// 登录校验 if (code.equals(cachedCode)) { SysUser sysUser = userService.selectUserByPhone(phone); LoginUser loginUser = (LoginUser) userDetailsServiceImpl.createLoginUser(sysUser); return tokenService.createToken(loginUser); -// return true; + // return true; } else { throw new ServiceException("验证码错误"); } - }else if(use.equals(OauthVerificationUse.REGISTER )&& !havePhoneFlag){//注册校验 + } else if (use.equals(OauthVerificationUse.REGISTER) && !havePhoneFlag) {// 注册校验 if (code.equals(cachedCode)) { return Boolean.toString(true); } else { throw new ServiceException("验证码错误"); } - }else if(use.equals(OauthVerificationUse.DISABLE )&& havePhoneFlag){//注销校验 + } else if (use.equals(OauthVerificationUse.DISABLE) && havePhoneFlag) {// 注销校验 if (code.equals(cachedCode)) { return Boolean.toString(true); } else { throw new ServiceException("验证码错误"); } - }else if(use.equals(OauthVerificationUse.RESET_PASSWORD )&& havePhoneFlag){//重置密码校验 + } else if (use.equals(OauthVerificationUse.RESET_PASSWORD) && havePhoneFlag) {// 重置密码校验 if (code.equals(cachedCode)) { return Boolean.toString(true); } else { throw new ServiceException("验证码错误"); } - }else if(use.equals(OauthVerificationUse.RESET_PHONE )&& !havePhoneFlag){//重置账号校验 + } else if (use.equals(OauthVerificationUse.RESET_PHONE) && !havePhoneFlag) {// 重置账号校验 if (code.equals(cachedCode)) { return Boolean.toString(true); } else { @@ -134,7 +132,7 @@ public class DySmsServiceImpl implements DySmsService, OauthVerificationCodeServ @Override public String doLogin(String phone) { - String verify = redisCache.getCacheObject("phone_codes_login" + phone); + String verify = CacheUtils.get(CACHE_NAME, phone + OauthVerificationUse.LOGIN, String.class); if (verify != null) { throw new ServiceException("该手机号验证码未过期"); } @@ -147,7 +145,8 @@ public class DySmsServiceImpl implements DySmsService, OauthVerificationCodeServ JSONObject templateParams = new JSONObject(); templateParams.put("code", code); dySmsUtil.sendSms(DySmsTemplate.Test_TEMPLATE_CODE, templateParams, phone); - redisCache.setCacheObject("phone_codes_login" + phone, code, 1, TimeUnit.MINUTES); + CacheUtils.put(CACHE_NAME, phone + OauthVerificationUse.LOGIN, code, 1, + TimeUnit.MINUTES); } catch (Exception e) { e.printStackTrace(); } @@ -155,7 +154,7 @@ public class DySmsServiceImpl implements DySmsService, OauthVerificationCodeServ } public String doLoginVerify(String phone, String code) { - String verify = redisCache.getCacheObject("phone_codes_login" + phone); + String verify = CacheUtils.get(CACHE_NAME, phone + OauthVerificationUse.LOGIN, String.class); if (code.equals(verify)) { SysUser sysUser = userService.selectUserByPhone(phone); LoginUser loginUser = (LoginUser) userDetailsServiceImpl.createLoginUser(sysUser); @@ -167,14 +166,14 @@ public class DySmsServiceImpl implements DySmsService, OauthVerificationCodeServ public String doRegister(String phone) { String code = generateRandomString(6); - redisCache.setCacheObject("phone_codes_register" + phone, code, 1, TimeUnit.MINUTES); - String verify = redisCache.getCacheObject("phone_codes_register" + phone); + CacheUtils.put(CACHE_NAME, phone + OauthVerificationUse.REGISTER, code, 1, TimeUnit.MINUTES); + String verify = CacheUtils.get("phone_codes_register", phone, String.class); if (verify != null) { throw new ServiceException("该手机号验证码未过期"); } else { try { dySmsUtil.sendSms(null, null, phone); - redisCache.setCacheObject("phone_codes_register" + phone, code, 1, TimeUnit.MINUTES); + CacheUtils.put(CACHE_NAME, phone + OauthVerificationUse.REGISTER, code, 1, TimeUnit.MINUTES); } catch (Exception e) { e.printStackTrace(); } diff --git a/ruoyi-pay/pom.xml b/ruoyi-pay/pom.xml index 1d1a017..00d3ea8 100644 --- a/ruoyi-pay/pom.xml +++ b/ruoyi-pay/pom.xml @@ -20,13 +20,6 @@ - - - com.ruoyi - ruoyi-common - ${ruoyi.version} - - com.ruoyi