diff --git a/pom.xml b/pom.xml index 6bcf6522..ee9060ef 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,7 @@ 3.2.2 2.12.2 5.7.16 + 3.16.7 @@ -217,6 +218,13 @@ ${hutool.version} + + + org.redisson + redisson-spring-boot-starter + ${redisson.version} + + com.ruoyi diff --git a/ruoyi-common/ruoyi-common-redis/pom.xml b/ruoyi-common/ruoyi-common-redis/pom.xml index 754c4704..00fa74c1 100644 --- a/ruoyi-common/ruoyi-common-redis/pom.xml +++ b/ruoyi-common/ruoyi-common-redis/pom.xml @@ -22,6 +22,12 @@ org.springframework.boot spring-boot-starter-data-redis + + + + org.redisson + redisson-spring-boot-starter + diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/config/RedisConfig.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/config/RedisConfig.java new file mode 100644 index 00000000..2f1c008f --- /dev/null +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/config/RedisConfig.java @@ -0,0 +1,198 @@ +package com.ruoyi.common.redis.config; + +import cn.hutool.core.util.ObjectUtil; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.redis.config.properties.RedissonProperties; +import lombok.extern.slf4j.Slf4j; +import org.redisson.Redisson; +import org.redisson.api.RedissonClient; +import org.redisson.codec.JsonJacksonCodec; +import org.redisson.config.Config; +import org.redisson.spring.cache.CacheConfig; +import org.redisson.spring.cache.RedissonSpringCacheManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.data.redis.RedisProperties; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * redis配置 + * + * @author Lion Li + */ +@Slf4j +@Configuration +@EnableCaching +public class RedisConfig extends CachingConfigurerSupport { + + private static final String REDIS_PROTOCOL_PREFIX = "redis://"; + private static final String REDISS_PROTOCOL_PREFIX = "rediss://"; + + @Autowired + private RedisProperties redisProperties; + + @Autowired + private RedissonProperties redissonProperties; + + @Bean(destroyMethod = "shutdown") + @ConditionalOnMissingBean(RedissonClient.class) + public RedissonClient redisson() throws IOException { + String prefix = REDIS_PROTOCOL_PREFIX; + if (redisProperties.isSsl()) { + prefix = REDISS_PROTOCOL_PREFIX; + } + Config config = new Config(); + config.setThreads(redissonProperties.getThreads()) + .setNettyThreads(redissonProperties.getNettyThreads()) + .setCodec(JsonJacksonCodec.INSTANCE) + .setTransportMode(redissonProperties.getTransportMode()); + + RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig(); + if (ObjectUtil.isNotNull(singleServerConfig)) { + // 使用单机模式 + config.useSingleServer() + .setAddress(prefix + redisProperties.getHost() + ":" + redisProperties.getPort()) + .setConnectTimeout(((Long) redisProperties.getTimeout().toMillis()).intValue()) + .setDatabase(redisProperties.getDatabase()) + .setPassword(StringUtils.isNotBlank(redisProperties.getPassword()) ? redisProperties.getPassword() : null) + .setTimeout(singleServerConfig.getTimeout()) + .setRetryAttempts(singleServerConfig.getRetryAttempts()) + .setRetryInterval(singleServerConfig.getRetryInterval()) + .setSubscriptionsPerConnection(singleServerConfig.getSubscriptionsPerConnection()) + .setClientName(singleServerConfig.getClientName()) + .setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout()) + .setSubscriptionConnectionMinimumIdleSize(singleServerConfig.getSubscriptionConnectionMinimumIdleSize()) + .setSubscriptionConnectionPoolSize(singleServerConfig.getSubscriptionConnectionPoolSize()) + .setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize()) + .setConnectionPoolSize(singleServerConfig.getConnectionPoolSize()) + .setDnsMonitoringInterval(singleServerConfig.getDnsMonitoringInterval()); + } + // 集群配置方式 参考下方注释 + RedissonProperties.ClusterServersConfig clusterServersConfig = redissonProperties.getClusterServersConfig(); + if (ObjectUtil.isNotNull(clusterServersConfig)) { + // 使用集群模式 + String finalPrefix = prefix; + List nodes = redisProperties.getCluster().getNodes() + .stream() + .map(node -> finalPrefix + node) + .collect(Collectors.toList()); + + config.useClusterServers() + .setConnectTimeout(((Long) redisProperties.getTimeout().toMillis()).intValue()) + .setPassword(StringUtils.isNotBlank(redisProperties.getPassword()) ? redisProperties.getPassword() : null) + .setTimeout(clusterServersConfig.getTimeout()) + .setRetryAttempts(clusterServersConfig.getRetryAttempts()) + .setRetryInterval(clusterServersConfig.getRetryInterval()) + .setSubscriptionsPerConnection(clusterServersConfig.getSubscriptionsPerConnection()) + .setClientName(clusterServersConfig.getClientName()) + .setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout()) + .setPingConnectionInterval(clusterServersConfig.getPingConnectionInterval()) + .setSubscriptionConnectionMinimumIdleSize(clusterServersConfig.getSubscriptionConnectionMinimumIdleSize()) + .setSubscriptionConnectionPoolSize(clusterServersConfig.getSubscriptionConnectionPoolSize()) + .setMasterConnectionMinimumIdleSize(clusterServersConfig.getMasterConnectionMinimumIdleSize()) + .setMasterConnectionPoolSize(clusterServersConfig.getMasterConnectionPoolSize()) + .setSlaveConnectionMinimumIdleSize(clusterServersConfig.getSlaveConnectionMinimumIdleSize()) + .setSlaveConnectionPoolSize(clusterServersConfig.getSlaveConnectionPoolSize()) + .setDnsMonitoringInterval(clusterServersConfig.getDnsMonitoringInterval()) + .setFailedSlaveReconnectionInterval(clusterServersConfig.getFailedSlaveReconnectionInterval()) + .setScanInterval(clusterServersConfig.getScanInterval()) + .setReadMode(clusterServersConfig.getReadMode()) + .setSubscriptionMode(clusterServersConfig.getSubscriptionMode()) + .setNodeAddresses(nodes); + } + RedissonClient redissonClient = Redisson.create(config); + log.info("初始化 redis 配置"); + return redissonClient; + } + + /** + * 整合spring-cache + */ + @Bean + public CacheManager cacheManager(RedissonClient redissonClient) { + List cacheGroup = redissonProperties.getCacheGroup(); + Map config = new HashMap<>(); + for (RedissonProperties.CacheGroup group : cacheGroup) { + CacheConfig cacheConfig = new CacheConfig(group.getTtl(), group.getMaxIdleTime()); + cacheConfig.setMaxSize(group.getMaxSize()); + config.put(group.getGroupId(), cacheConfig); + } + return new RedissonSpringCacheManager(redissonClient, config, JsonJacksonCodec.INSTANCE); + } + + /** + * redis集群配置 yml + * + * --- # redis 集群配置(单机与集群只能开启一个另一个需要注释掉) + * spring: + * redis: + * cluster: + * nodes: + * - 192.168.0.100:6379 + * - 192.168.0.101:6379 + * - 192.168.0.102:6379 + * # 密码 + * password: + * # 连接超时时间 + * timeout: 10s + * # 是否开启ssl + * ssl: false + * + * redisson: + * # 线程池数量 + * threads: 16 + * # Netty线程池数量 + * nettyThreads: 32 + * # 传输模式 + * transportMode: "NIO" + * # 集群配置 + * clusterServersConfig: + * # 客户端名称 + * clientName: ${ruoyi.name} + * # master最小空闲连接数 + * masterConnectionMinimumIdleSize: 32 + * # master连接池大小 + * masterConnectionPoolSize: 64 + * # slave最小空闲连接数 + * slaveConnectionMinimumIdleSize: 32 + * # slave连接池大小 + * slaveConnectionPoolSize: 64 + * # 连接空闲超时,单位:毫秒 + * idleConnectionTimeout: 10000 + * # ping连接间隔 + * pingConnectionInterval: 1000 + * # 命令等待超时,单位:毫秒 + * timeout: 3000 + * # 如果尝试在此限制之内发送成功,则开始启用 timeout 计时。 + * retryAttempts: 3 + * # 命令重试发送时间间隔,单位:毫秒 + * retryInterval: 1500 + * # 从可用服务器的内部列表中排除 Redis Slave 重新连接尝试的间隔。 + * failedSlaveReconnectionInterval: 3000 + * # 发布和订阅连接池最小空闲连接数 + * subscriptionConnectionMinimumIdleSize: 1 + * # 发布和订阅连接池大小 + * subscriptionConnectionPoolSize: 50 + * # 单个连接最大订阅数量 + * subscriptionsPerConnection: 5 + * # 扫描间隔 + * scanInterval: 1000 + * # DNS监测时间间隔,单位:毫秒 + * dnsMonitoringInterval: 5000 + * # 读取模式 + * readMode: "SLAVE" + * # 订阅模式 + * subscriptionMode: "MASTER" + */ + +} diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/config/properties/RedissonProperties.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/config/properties/RedissonProperties.java new file mode 100644 index 00000000..593de9ee --- /dev/null +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/config/properties/RedissonProperties.java @@ -0,0 +1,236 @@ +package com.ruoyi.common.redis.config.properties; + +import lombok.Data; +import lombok.NoArgsConstructor; +import org.redisson.config.ReadMode; +import org.redisson.config.SubscriptionMode; +import org.redisson.config.TransportMode; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * Redisson 配置属性 + * + * @author Lion Li + */ +@Data +@Component +@ConfigurationProperties(prefix = "redisson") +public class RedissonProperties { + + /** + * 线程池数量,默认值 = 当前处理核数量 * 2 + */ + private int threads; + + /** + * Netty线程池数量,默认值 = 当前处理核数量 * 2 + */ + private int nettyThreads; + + /** + * 传输模式 + */ + private TransportMode transportMode; + + /** + * 单机服务配置 + */ + private SingleServerConfig singleServerConfig; + + /** + * 集群服务配置 + */ + private ClusterServersConfig clusterServersConfig; + + /** + * 缓存组 + */ + private List cacheGroup; + + @Data + @NoArgsConstructor + public static class SingleServerConfig { + + /** + * 客户端名称 + */ + private String clientName; + + /** + * 最小空闲连接数 + */ + private int connectionMinimumIdleSize; + + /** + * 连接池大小 + */ + private int connectionPoolSize; + + /** + * 连接空闲超时,单位:毫秒 + */ + private int idleConnectionTimeout; + + /** + * 命令等待超时,单位:毫秒 + */ + private int timeout; + + /** + * 如果尝试在此限制之内发送成功,则开始启用 timeout 计时。 + */ + private int retryAttempts; + + /** + * 命令重试发送时间间隔,单位:毫秒 + */ + private int retryInterval; + + /** + * 发布和订阅连接的最小空闲连接数 + */ + private int subscriptionConnectionMinimumIdleSize; + + /** + * 发布和订阅连接池大小 + */ + private int subscriptionConnectionPoolSize; + + /** + * 单个连接最大订阅数量 + */ + private int subscriptionsPerConnection; + + /** + * DNS监测时间间隔,单位:毫秒 + */ + private int dnsMonitoringInterval; + + } + + @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; + + /** + * ping超时 + */ + private int pingConnectionInterval; + + /** + * 命令等待超时,单位:毫秒 + */ + private int timeout; + + /** + * 如果尝试在此限制之内发送成功,则开始启用 timeout 计时。 + */ + private int retryAttempts; + + /** + * 命令重试发送时间间隔,单位:毫秒 + */ + private int retryInterval; + + /** + * 错误重试次数 + */ + private int failedSlaveReconnectionInterval; + + /** + * 发布和订阅连接池最小空闲连接数 + */ + private int subscriptionConnectionMinimumIdleSize; + + /** + * 发布和订阅连接池大小 + */ + private int subscriptionConnectionPoolSize; + + /** + * 单个连接最大订阅数量 + */ + private int subscriptionsPerConnection; + + /** + * 扫描间隔 + */ + private int scanInterval; + + /** + * DNS监测时间间隔,单位:毫秒 + */ + private int dnsMonitoringInterval; + + /** + * 读取模式 + */ + private ReadMode readMode; + + /** + * 订阅模式 + */ + private SubscriptionMode subscriptionMode; + + } + + @Data + @NoArgsConstructor + public static class CacheGroup { + + /** + * 组id + */ + private String groupId; + + /** + * 组过期时间 + */ + private long ttl; + + /** + * 组最大空闲时间 + */ + private long maxIdleTime; + + /** + * 组最大长度 + */ + private int maxSize; + + } + +} diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/FastJson2JsonRedisSerializer.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/FastJson2JsonRedisSerializer.java deleted file mode 100644 index 012eeb8e..00000000 --- a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/FastJson2JsonRedisSerializer.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.ruoyi.common.redis.configure; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.serializer.SerializerFeature; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.type.TypeFactory; -import org.springframework.data.redis.serializer.RedisSerializer; -import org.springframework.data.redis.serializer.SerializationException; -import com.alibaba.fastjson.parser.ParserConfig; -import org.springframework.util.Assert; -import java.nio.charset.Charset; - -/** - * Redis使用FastJson序列化 - * - * @author ruoyi - */ -public class FastJson2JsonRedisSerializer implements RedisSerializer -{ - @SuppressWarnings("unused") - private ObjectMapper objectMapper = new ObjectMapper(); - - public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); - - private Class clazz; - - static - { - ParserConfig.getGlobalInstance().setAutoTypeSupport(true); - } - - public FastJson2JsonRedisSerializer(Class clazz) - { - super(); - this.clazz = clazz; - } - - @Override - public byte[] serialize(T t) throws SerializationException - { - if (t == null) - { - return new byte[0]; - } - return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET); - } - - @Override - public T deserialize(byte[] bytes) throws SerializationException - { - if (bytes == null || bytes.length <= 0) - { - return null; - } - String str = new String(bytes, DEFAULT_CHARSET); - - return JSON.parseObject(str, clazz); - } - - public void setObjectMapper(ObjectMapper objectMapper) - { - Assert.notNull(objectMapper, "'objectMapper' must not be null"); - this.objectMapper = objectMapper; - } - - protected JavaType getJavaType(Class clazz) - { - return TypeFactory.defaultInstance().constructType(clazz); - } -} diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/RedisConfig.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/RedisConfig.java deleted file mode 100644 index 31238d63..00000000 --- a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/configure/RedisConfig.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.ruoyi.common.redis.configure; - -import org.springframework.cache.annotation.CachingConfigurerSupport; -import org.springframework.cache.annotation.EnableCaching; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.serializer.StringRedisSerializer; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; - -/** - * redis配置 - * - * @author ruoyi - */ -@Configuration -@EnableCaching -public class RedisConfig extends CachingConfigurerSupport -{ - @Bean - @SuppressWarnings(value = { "unchecked", "rawtypes" }) - public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) - { - RedisTemplate template = new RedisTemplate<>(); - template.setConnectionFactory(connectionFactory); - - FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); - - ObjectMapper mapper = new ObjectMapper(); - mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); - mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); - serializer.setObjectMapper(mapper); - - // 使用StringRedisSerializer来序列化和反序列化redis的key值 - template.setKeySerializer(new StringRedisSerializer()); - template.setValueSerializer(serializer); - - // Hash的key也采用StringRedisSerializer的序列化方式 - template.setHashKeySerializer(new StringRedisSerializer()); - template.setHashValueSerializer(serializer); - - template.afterPropertiesSet(); - return template; - } -} diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/service/RedisService.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/service/RedisService.java deleted file mode 100644 index 82efb9b1..00000000 --- a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/service/RedisService.java +++ /dev/null @@ -1,256 +0,0 @@ -package com.ruoyi.common.redis.service; - -import java.util.Collection; -import java.util.Iterator; -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.data.redis.core.BoundSetOperations; -import org.springframework.data.redis.core.HashOperations; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.core.ValueOperations; -import org.springframework.stereotype.Component; - -/** - * spring redis 工具类 - * - * @author ruoyi - **/ -@SuppressWarnings(value = { "unchecked", "rawtypes" }) -@Component -public class RedisService -{ - @Autowired - public RedisTemplate redisTemplate; - - /** - * 缓存基本的对象,Integer、String、实体类等 - * - * @param key 缓存的键值 - * @param value 缓存的值 - */ - public void setCacheObject(final String key, final T value) - { - redisTemplate.opsForValue().set(key, value); - } - - /** - * 缓存基本的对象,Integer、String、实体类等 - * - * @param key 缓存的键值 - * @param value 缓存的值 - * @param timeout 时间 - * @param timeUnit 时间颗粒度 - */ - public void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit) - { - redisTemplate.opsForValue().set(key, value, timeout, timeUnit); - } - - /** - * 设置有效时间 - * - * @param key Redis键 - * @param timeout 超时时间 - * @return true=设置成功;false=设置失败 - */ - public boolean expire(final String key, final long timeout) - { - return expire(key, timeout, TimeUnit.SECONDS); - } - - /** - * 设置有效时间 - * - * @param key Redis键 - * @param timeout 超时时间 - * @param unit 时间单位 - * @return true=设置成功;false=设置失败 - */ - public boolean expire(final String key, final long timeout, final TimeUnit unit) - { - return redisTemplate.expire(key, timeout, unit); - } - - /** - * 获取有效时间 - * - * @param key Redis键 - * @return 有效时间 - */ - public long getExpire(final String key) - { - return redisTemplate.getExpire(key); - } - - /** - * 判断 key是否存在 - * - * @param key 键 - * @return true 存在 false不存在 - */ - public Boolean hasKey(String key) - { - return redisTemplate.hasKey(key); - } - - /** - * 获得缓存的基本对象。 - * - * @param key 缓存键值 - * @return 缓存键值对应的数据 - */ - public T getCacheObject(final String key) - { - ValueOperations operation = redisTemplate.opsForValue(); - return operation.get(key); - } - - /** - * 删除单个对象 - * - * @param key - */ - public boolean deleteObject(final String key) - { - return redisTemplate.delete(key); - } - - /** - * 删除集合对象 - * - * @param collection 多个对象 - * @return - */ - public long deleteObject(final Collection collection) - { - return redisTemplate.delete(collection); - } - - /** - * 缓存List数据 - * - * @param key 缓存的键值 - * @param dataList 待缓存的List数据 - * @return 缓存的对象 - */ - public long setCacheList(final String key, final List dataList) - { - Long count = redisTemplate.opsForList().rightPushAll(key, dataList); - return count == null ? 0 : count; - } - - /** - * 获得缓存的list对象 - * - * @param key 缓存的键值 - * @return 缓存键值对应的数据 - */ - public List getCacheList(final String key) - { - return redisTemplate.opsForList().range(key, 0, -1); - } - - /** - * 缓存Set - * - * @param key 缓存键值 - * @param dataSet 缓存的数据 - * @return 缓存数据的对象 - */ - public BoundSetOperations setCacheSet(final String key, final Set dataSet) - { - BoundSetOperations setOperation = redisTemplate.boundSetOps(key); - Iterator it = dataSet.iterator(); - while (it.hasNext()) - { - setOperation.add(it.next()); - } - return setOperation; - } - - /** - * 获得缓存的set - * - * @param key - * @return - */ - public Set getCacheSet(final String key) - { - return redisTemplate.opsForSet().members(key); - } - - /** - * 缓存Map - * - * @param key - * @param dataMap - */ - public void setCacheMap(final String key, final Map dataMap) - { - if (dataMap != null) { - redisTemplate.opsForHash().putAll(key, dataMap); - } - } - - /** - * 获得缓存的Map - * - * @param key - * @return - */ - public Map getCacheMap(final String key) - { - return redisTemplate.opsForHash().entries(key); - } - - /** - * 往Hash中存入数据 - * - * @param key Redis键 - * @param hKey Hash键 - * @param value 值 - */ - public void setCacheMapValue(final String key, final String hKey, final T value) - { - redisTemplate.opsForHash().put(key, hKey, value); - } - - /** - * 获取Hash中的数据 - * - * @param key Redis键 - * @param hKey Hash键 - * @return Hash中的对象 - */ - public T getCacheMapValue(final String key, final String hKey) - { - HashOperations opsForHash = redisTemplate.opsForHash(); - return opsForHash.get(key, hKey); - } - - /** - * 获取多个Hash中的数据 - * - * @param key Redis键 - * @param hKeys Hash键集合 - * @return Hash对象集合 - */ - public List getMultiCacheMapValue(final String key, final Collection hKeys) - { - return redisTemplate.opsForHash().multiGet(key, hKeys); - } - - /** - * 获得缓存的基本对象列表 - * - * @param pattern 字符串前缀 - * @return 对象列表 - */ - public Collection keys(final String pattern) - { - return redisTemplate.keys(pattern); - } -} diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/utils/RedisUtils.java b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/utils/RedisUtils.java new file mode 100644 index 00000000..4c290eba --- /dev/null +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/utils/RedisUtils.java @@ -0,0 +1,394 @@ +package com.ruoyi.common.redis.utils; + +import cn.hutool.core.collection.IterUtil; +import com.ruoyi.common.core.utils.SpringUtils; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.redisson.api.*; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +/** + * redis 工具类 + * + * @author Lion Li + * @version 3.1.0 新增 + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +@SuppressWarnings(value = {"unchecked", "rawtypes"}) +public class RedisUtils { + + private static final RedissonClient CLIENT = SpringUtils.getBean(RedissonClient.class); + + /** + * 限流 + * + * @param key 限流key + * @param rateType 限流类型 + * @param rate 速率 + * @param rateInterval 速率间隔 + * @return -1 表示失败 + */ + public static long rateLimiter(String key, RateType rateType, int rate, int rateInterval) { + RRateLimiter rateLimiter = CLIENT.getRateLimiter(key); + rateLimiter.trySetRate(rateType, rate, rateInterval, RateIntervalUnit.SECONDS); + if (rateLimiter.tryAcquire()) { + return rateLimiter.availablePermits(); + } else { + return -1L; + } + } + + /** + * 获取客户端实例 + */ + public static RedissonClient getClient() { + return CLIENT; + } + + /** + * 发布通道消息 + * + * @param channelKey 通道key + * @param msg 发送数据 + * @param consumer 自定义处理 + */ + public static void publish(String channelKey, T msg, Consumer consumer) { + RTopic topic = CLIENT.getTopic(channelKey); + topic.publish(msg); + consumer.accept(msg); + } + + public static void publish(String channelKey, T msg) { + RTopic topic = CLIENT.getTopic(channelKey); + topic.publish(msg); + } + + /** + * 订阅通道接收消息 + * + * @param channelKey 通道key + * @param clazz 消息类型 + * @param consumer 自定义处理 + */ + public static void subscribe(String channelKey, Class clazz, Consumer consumer) { + RTopic topic = CLIENT.getTopic(channelKey); + topic.addListener(clazz, (channel, msg) -> consumer.accept(msg)); + } + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + */ + public static void setCacheObject(final String key, final T value) { + setCacheObject(key, value, false); + } + + /** + * 缓存基本的对象,保留当前对象 TTL 有效期 + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @param isSaveTtl 是否保留TTL有效期(例如: set之前ttl剩余90 set之后还是为90) + * @since Redis 6.X 以上使用 setAndKeepTTL 兼容 5.X 方案 + */ + public static void setCacheObject(final String key, final T value, final boolean isSaveTtl) { + RBucket bucket = CLIENT.getBucket(key); + if (isSaveTtl) { + try { + bucket.setAndKeepTTL(value); + } catch (Exception e) { + long timeToLive = bucket.remainTimeToLive(); + bucket.set(value); + bucket.expire(timeToLive, TimeUnit.MILLISECONDS); + } + } else { + bucket.set(value); + } + } + + /** + * 缓存基本的对象,Integer、String、实体类等 + * + * @param key 缓存的键值 + * @param value 缓存的值 + * @param timeout 时间 + * @param timeUnit 时间颗粒度 + */ + public static void setCacheObject(final String key, final T value, final long timeout, final TimeUnit timeUnit) { + RBucket result = CLIENT.getBucket(key); + result.set(value); + result.expire(timeout, timeUnit); + } + + /** + * 注册对象监听器 + * + * key 监听器需开启 `notify-keyspace-events` 等 redis 相关配置 + * + * @param key 缓存的键值 + * @param listener 监听器配置 + */ + public static void addObjectListener(final String key, final ObjectListener listener) { + RBucket result = CLIENT.getBucket(key); + result.addListener(listener); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @return true=设置成功;false=设置失败 + */ + public static boolean expire(final String key, final long timeout) { + return expire(key, timeout, TimeUnit.SECONDS); + } + + /** + * 设置有效时间 + * + * @param key Redis键 + * @param timeout 超时时间 + * @param unit 时间单位 + * @return true=设置成功;false=设置失败 + */ + public static boolean expire(final String key, final long timeout, final TimeUnit unit) { + RBucket rBucket = CLIENT.getBucket(key); + return rBucket.expire(timeout, unit); + } + + /** + * 获得缓存的基本对象。 + * + * @param key 缓存键值 + * @return 缓存键值对应的数据 + */ + public static T getCacheObject(final String key) { + RBucket rBucket = CLIENT.getBucket(key); + return rBucket.get(); + } + + /** + * 获得key剩余存活时间 + * + * @param key 缓存键值 + * @return 剩余存活时间 + */ + public static long getTimeToLive(final String key) { + RBucket rBucket = CLIENT.getBucket(key); + return rBucket.remainTimeToLive(); + } + + /** + * 删除单个对象 + * + * @param key 缓存的键值 + */ + public static boolean deleteObject(final String key) { + return CLIENT.getBucket(key).delete(); + } + + /** + * 删除集合对象 + * + * @param collection 多个对象 + */ + public static void deleteObject(final Collection collection) { + RBatch batch = CLIENT.createBatch(); + collection.forEach(t -> { + batch.getBucket(t.toString()).deleteAsync(); + }); + batch.execute(); + } + + /** + * 缓存List数据 + * + * @param key 缓存的键值 + * @param dataList 待缓存的List数据 + * @return 缓存的对象 + */ + public static boolean setCacheList(final String key, final List dataList) { + RList rList = CLIENT.getList(key); + return rList.addAll(dataList); + } + + /** + * 注册List监听器 + * + * key 监听器需开启 `notify-keyspace-events` 等 redis 相关配置 + * + * @param key 缓存的键值 + * @param listener 监听器配置 + */ + public static void addListListener(final String key, final ObjectListener listener) { + RList rList = CLIENT.getList(key); + rList.addListener(listener); + } + + /** + * 获得缓存的list对象 + * + * @param key 缓存的键值 + * @return 缓存键值对应的数据 + */ + public static List getCacheList(final String key) { + RList rList = CLIENT.getList(key); + return rList.readAll(); + } + + /** + * 缓存Set + * + * @param key 缓存键值 + * @param dataSet 缓存的数据 + * @return 缓存数据的对象 + */ + public static boolean setCacheSet(final String key, final Set dataSet) { + RSet rSet = CLIENT.getSet(key); + return rSet.addAll(dataSet); + } + + /** + * 注册Set监听器 + * + * key 监听器需开启 `notify-keyspace-events` 等 redis 相关配置 + * + * @param key 缓存的键值 + * @param listener 监听器配置 + */ + public static void addSetListener(final String key, final ObjectListener listener) { + RSet rSet = CLIENT.getSet(key); + rSet.addListener(listener); + } + + /** + * 获得缓存的set + * + * @param key 缓存的key + * @return set对象 + */ + public static Set getCacheSet(final String key) { + RSet rSet = CLIENT.getSet(key); + return rSet.readAll(); + } + + /** + * 缓存Map + * + * @param key 缓存的键值 + * @param dataMap 缓存的数据 + */ + public static void setCacheMap(final String key, final Map dataMap) { + if (dataMap != null) { + RMap rMap = CLIENT.getMap(key); + rMap.putAll(dataMap); + } + } + + /** + * 注册Map监听器 + * + * key 监听器需开启 `notify-keyspace-events` 等 redis 相关配置 + * + * @param key 缓存的键值 + * @param listener 监听器配置 + */ + public static void addMapListener(final String key, final ObjectListener listener) { + RMap rMap = CLIENT.getMap(key); + rMap.addListener(listener); + } + + /** + * 获得缓存的Map + * + * @param key 缓存的键值 + * @return map对象 + */ + public static Map getCacheMap(final String key) { + RMap rMap = CLIENT.getMap(key); + return rMap.getAll(rMap.keySet()); + } + + /** + * 往Hash中存入数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @param value 值 + */ + public static void setCacheMapValue(final String key, final String hKey, final T value) { + RMap rMap = CLIENT.getMap(key); + rMap.put(hKey, value); + } + + /** + * 获取Hash中的数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return Hash中的对象 + */ + public static T getCacheMapValue(final String key, final String hKey) { + RMap rMap = CLIENT.getMap(key); + return rMap.get(hKey); + } + + /** + * 删除Hash中的数据 + * + * @param key Redis键 + * @param hKey Hash键 + * @return Hash中的对象 + */ + public static T delCacheMapValue(final String key, final String hKey) { + RMap rMap = CLIENT.getMap(key); + return rMap.remove(hKey); + } + + /** + * 获取多个Hash中的数据 + * + * @param key Redis键 + * @param hKeys Hash键集合 + * @return Hash对象集合 + */ + public static Map getMultiCacheMapValue(final String key, final Set hKeys) { + RMap rMap = CLIENT.getMap(key); + return rMap.getAll(hKeys); + } + + /** + * 获得缓存的基本对象列表 + * + * @param pattern 字符串前缀 + * @return 对象列表 + */ + public static Collection keys(final String pattern) { + Iterable iterable = CLIENT.getKeys().getKeysByPattern(pattern); + return IterUtil.toList(iterable); + } + + /** + * 检查redis中是否存在key + * @param key 键 + * @return + */ + public static Boolean hasKey(String key){ + RKeys rKeys= CLIENT.getKeys(); + if(rKeys.countExists(key)>0){ + return true; + }else { + return false; + } + } + +} diff --git a/ruoyi-common/ruoyi-common-redis/src/main/resources/META-INF/spring.factories b/ruoyi-common/ruoyi-common-redis/src/main/resources/META-INF/spring.factories index 60d1d47b..36b264e0 100644 --- a/ruoyi-common/ruoyi-common-redis/src/main/resources/META-INF/spring.factories +++ b/ruoyi-common/ruoyi-common-redis/src/main/resources/META-INF/spring.factories @@ -1,5 +1,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - com.ruoyi.common.redis.configure.RedisConfig,\ - com.ruoyi.common.redis.service.RedisService + com.ruoyi.common.redis.config.RedisConfig,\ + com.ruoyi.common.redis.config.properties.RedissonProperties diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java index 60eeee0b..396e901f 100644 --- a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java @@ -1,11 +1,5 @@ package com.ruoyi.common.security.service; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import javax.servlet.http.HttpServletRequest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import com.ruoyi.common.core.constant.CacheConstants; import com.ruoyi.common.core.constant.SecurityConstants; import com.ruoyi.common.core.utils.IdUtils; @@ -13,9 +7,15 @@ import com.ruoyi.common.core.utils.JwtUtils; import com.ruoyi.common.core.utils.ServletUtils; import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.ip.IpUtils; -import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.common.redis.utils.RedisUtils; import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.system.api.model.LoginUser; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; /** * token验证处理 @@ -25,8 +25,6 @@ import com.ruoyi.system.api.model.LoginUser; @Component public class TokenService { - @Autowired - private RedisService redisService; protected static final long MILLIS_SECOND = 1000; @@ -100,7 +98,7 @@ public class TokenService if (StringUtils.isNotEmpty(token)) { String userkey = JwtUtils.getUserKey(token); - user = redisService.getCacheObject(getTokenKey(userkey)); + user= RedisUtils.getCacheObject(getTokenKey(userkey)); return user; } } @@ -129,7 +127,7 @@ public class TokenService if (StringUtils.isNotEmpty(token)) { String userkey = JwtUtils.getUserKey(token); - redisService.deleteObject(getTokenKey(userkey)); + RedisUtils.deleteObject(getTokenKey(userkey)); } } @@ -159,7 +157,7 @@ public class TokenService loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE); // 根据uuid将loginUser缓存 String userKey = getTokenKey(loginUser.getToken()); - redisService.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); + RedisUtils.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); } private String getTokenKey(String token) diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/utils/DictUtils.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/utils/DictUtils.java index 76206396..920d027a 100644 --- a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/utils/DictUtils.java +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/utils/DictUtils.java @@ -1,13 +1,13 @@ package com.ruoyi.common.security.utils; -import java.util.Collection; -import java.util.List; import com.ruoyi.common.core.constant.Constants; -import com.ruoyi.common.core.utils.SpringUtils; import com.ruoyi.common.core.utils.StringUtils; -import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.common.redis.utils.RedisUtils; import com.ruoyi.system.api.domain.SysDictData; +import java.util.Collection; +import java.util.List; + /** * 字典工具类 * @@ -23,7 +23,7 @@ public class DictUtils */ public static void setDictCache(String key, List dictDatas) { - SpringUtils.getBean(RedisService.class).setCacheObject(getCacheKey(key), dictDatas); + RedisUtils.setCacheObject(getCacheKey(key), dictDatas); } /** @@ -34,7 +34,7 @@ public class DictUtils */ public static List getDictCache(String key) { - Object cacheObj = SpringUtils.getBean(RedisService.class).getCacheObject(getCacheKey(key)); + Object cacheObj = RedisUtils.getCacheObject(getCacheKey(key)); if (StringUtils.isNotNull(cacheObj)) { List dictDatas = StringUtils.cast(cacheObj); @@ -50,7 +50,7 @@ public class DictUtils */ public static void removeDictCache(String key) { - SpringUtils.getBean(RedisService.class).deleteObject(getCacheKey(key)); + RedisUtils.deleteObject(getCacheKey(key)); } /** @@ -58,8 +58,8 @@ public class DictUtils */ public static void clearDictCache() { - Collection keys = SpringUtils.getBean(RedisService.class).keys(Constants.SYS_DICT_KEY + "*"); - SpringUtils.getBean(RedisService.class).deleteObject(keys); + Collection keys = RedisUtils.keys(Constants.SYS_DICT_KEY + "*"); + RedisUtils.deleteObject(keys); } /** diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java index 6e1e68a1..5f7df952 100644 --- a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/filter/AuthFilter.java @@ -1,6 +1,15 @@ package com.ruoyi.gateway.filter; import cn.hutool.json.JSONObject; +import com.ruoyi.common.core.constant.CacheConstants; +import com.ruoyi.common.core.constant.HttpStatus; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.constant.TokenConstants; +import com.ruoyi.common.core.utils.JwtUtils; +import com.ruoyi.common.core.utils.ServletUtils; +import com.ruoyi.common.core.utils.StringUtils; +import com.ruoyi.common.redis.utils.RedisUtils; +import com.ruoyi.gateway.config.properties.IgnoreWhiteProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -10,15 +19,6 @@ import org.springframework.core.Ordered; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; -import com.ruoyi.common.core.constant.CacheConstants; -import com.ruoyi.common.core.constant.HttpStatus; -import com.ruoyi.common.core.constant.SecurityConstants; -import com.ruoyi.common.core.constant.TokenConstants; -import com.ruoyi.common.core.utils.JwtUtils; -import com.ruoyi.common.core.utils.ServletUtils; -import com.ruoyi.common.core.utils.StringUtils; -import com.ruoyi.common.redis.service.RedisService; -import com.ruoyi.gateway.config.properties.IgnoreWhiteProperties; import reactor.core.publisher.Mono; /** @@ -35,10 +35,6 @@ public class AuthFilter implements GlobalFilter, Ordered @Autowired private IgnoreWhiteProperties ignoreWhite; - @Autowired - private RedisService redisService; - - @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { @@ -62,7 +58,7 @@ public class AuthFilter implements GlobalFilter, Ordered return unauthorizedResponse(exchange, "令牌已过期或验证不正确!"); } String userkey = JwtUtils.getUserKey(claims); - boolean islogin = redisService.hasKey(getTokenKey(userkey)); + boolean islogin = RedisUtils.hasKey(getTokenKey(userkey)); if (!islogin) { return unauthorizedResponse(exchange, "登录状态已过期"); diff --git a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java index 368a9fc9..f60d97a4 100644 --- a/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java +++ b/ruoyi-gateway/src/main/java/com/ruoyi/gateway/service/impl/ValidateCodeServiceImpl.java @@ -1,13 +1,5 @@ package com.ruoyi.gateway.service.impl; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.util.concurrent.TimeUnit; -import javax.annotation.Resource; -import javax.imageio.ImageIO; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.FastByteArrayOutputStream; import com.google.code.kaptcha.Producer; import com.ruoyi.common.core.constant.Constants; import com.ruoyi.common.core.exception.CaptchaException; @@ -15,9 +7,18 @@ import com.ruoyi.common.core.utils.IdUtils; import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.sign.Base64; import com.ruoyi.common.core.web.domain.AjaxResult; -import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.common.redis.utils.RedisUtils; import com.ruoyi.gateway.config.properties.CaptchaProperties; import com.ruoyi.gateway.service.ValidateCodeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.FastByteArrayOutputStream; + +import javax.annotation.Resource; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.concurrent.TimeUnit; /** * 验证码实现处理 @@ -33,9 +34,6 @@ public class ValidateCodeServiceImpl implements ValidateCodeService @Resource(name = "captchaProducerMath") private Producer captchaProducerMath; - @Autowired - private RedisService redisService; - @Autowired private CaptchaProperties captchaProperties; @@ -75,7 +73,7 @@ public class ValidateCodeServiceImpl implements ValidateCodeService image = captchaProducer.createImage(capStr); } - redisService.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); + RedisUtils.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); // 转换流信息写出 FastByteArrayOutputStream os = new FastByteArrayOutputStream(); try @@ -107,8 +105,8 @@ public class ValidateCodeServiceImpl implements ValidateCodeService throw new CaptchaException("验证码已失效"); } String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid; - String captcha = redisService.getCacheObject(verifyKey); - redisService.deleteObject(verifyKey); + String captcha = RedisUtils.getCacheObject(verifyKey); + RedisUtils.deleteObject(verifyKey); if (!code.equalsIgnoreCase(captcha)) { diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserOnlineController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserOnlineController.java index 4863d3bb..52172e59 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserOnlineController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserOnlineController.java @@ -1,15 +1,5 @@ package com.ruoyi.system.controller; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; import com.ruoyi.common.core.constant.CacheConstants; import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.web.controller.BaseController; @@ -17,11 +7,18 @@ import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.web.page.TableDataInfo; import com.ruoyi.common.log.annotation.Log; import com.ruoyi.common.log.enums.BusinessType; -import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.common.redis.utils.RedisUtils; import com.ruoyi.common.security.annotation.RequiresPermissions; import com.ruoyi.system.api.model.LoginUser; import com.ruoyi.system.domain.SysUserOnline; import com.ruoyi.system.service.ISysUserOnlineService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; /** * 在线用户监控 @@ -35,18 +32,15 @@ public class SysUserOnlineController extends BaseController @Autowired private ISysUserOnlineService userOnlineService; - @Autowired - private RedisService redisService; - @RequiresPermissions("monitor:online:list") @GetMapping("/list") public TableDataInfo list(String ipaddr, String userName) { - Collection keys = redisService.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"); + Collection keys = RedisUtils.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"); List userOnlineList = new ArrayList(); for (String key : keys) { - LoginUser user = redisService.getCacheObject(key); + LoginUser user = RedisUtils.getCacheObject(key); if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) { if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) @@ -86,7 +80,7 @@ public class SysUserOnlineController extends BaseController @DeleteMapping("/{tokenId}") public AjaxResult forceLogout(@PathVariable String tokenId) { - redisService.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId); + RedisUtils.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId); return AjaxResult.success(); } } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java index b1c1f730..29cf7abd 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysConfigServiceImpl.java @@ -1,19 +1,20 @@ package com.ruoyi.system.service.impl; -import java.util.Collection; -import java.util.List; -import javax.annotation.PostConstruct; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; import com.ruoyi.common.core.constant.Constants; import com.ruoyi.common.core.constant.UserConstants; import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.core.utils.StringUtils; -import com.ruoyi.common.redis.service.RedisService; +import com.ruoyi.common.redis.utils.RedisUtils; import com.ruoyi.system.domain.SysConfig; import com.ruoyi.system.mapper.SysConfigMapper; import com.ruoyi.system.service.ISysConfigService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.util.Collection; +import java.util.List; /** * 参数配置 服务层实现 @@ -26,9 +27,6 @@ public class SysConfigServiceImpl implements ISysConfigService @Autowired private SysConfigMapper configMapper; - @Autowired - private RedisService redisService; - /** * 项目启动时,初始化参数到缓存 */ @@ -61,7 +59,7 @@ public class SysConfigServiceImpl implements ISysConfigService @Override public String selectConfigByKey(String configKey) { - String configValue = Convert.toStr(redisService.getCacheObject(getCacheKey(configKey))); + String configValue = Convert.toStr(RedisUtils.getCacheObject(getCacheKey(configKey))); if (StringUtils.isNotEmpty(configValue)) { return configValue; @@ -71,7 +69,7 @@ public class SysConfigServiceImpl implements ISysConfigService SysConfig retConfig = configMapper.selectConfig(config); if (StringUtils.isNotNull(retConfig)) { - redisService.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue()); + RedisUtils.setCacheObject(getCacheKey(configKey), retConfig.getConfigValue()); return retConfig.getConfigValue(); } return StringUtils.EMPTY; @@ -101,7 +99,7 @@ public class SysConfigServiceImpl implements ISysConfigService int row = configMapper.insertConfig(config); if (row > 0) { - redisService.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + RedisUtils.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); } return row; } @@ -118,7 +116,7 @@ public class SysConfigServiceImpl implements ISysConfigService int row = configMapper.updateConfig(config); if (row > 0) { - redisService.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + RedisUtils.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); } return row; } @@ -140,7 +138,7 @@ public class SysConfigServiceImpl implements ISysConfigService throw new ServiceException(String.format("内置参数【%1$s】不能删除 ", config.getConfigKey())); } configMapper.deleteConfigById(configId); - redisService.deleteObject(getCacheKey(config.getConfigKey())); + RedisUtils.deleteObject(getCacheKey(config.getConfigKey())); } } @@ -153,7 +151,7 @@ public class SysConfigServiceImpl implements ISysConfigService List configsList = configMapper.selectConfigList(new SysConfig()); for (SysConfig config : configsList) { - redisService.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); + RedisUtils.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue()); } } @@ -163,8 +161,8 @@ public class SysConfigServiceImpl implements ISysConfigService @Override public void clearConfigCache() { - Collection keys = redisService.keys(Constants.SYS_CONFIG_KEY + "*"); - redisService.deleteObject(keys); + Collection keys = RedisUtils.keys(Constants.SYS_CONFIG_KEY + "*"); + RedisUtils.deleteObject(keys); } /** diff --git a/sql/ry_config_20211118.sql b/sql/ry_config_20211118.sql index a8ed2003..3a3f7dfe 100644 --- a/sql/ry_config_20211118.sql +++ b/sql/ry_config_20211118.sql @@ -32,7 +32,7 @@ CREATE TABLE `config_info` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info'; insert into config_info(id, data_id, group_id, content, md5, gmt_create, gmt_modified, src_user, src_ip, app_name, tenant_id, c_desc, c_use, effect, type, c_schema) values -(1,'application-dev.yml','DEFAULT_GROUP','spring:\n main:\n allow-bean-definition-overriding: true\n autoconfigure:\n exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure\n #jackson配置\n jackson:\n # 日期格式化\n date-format: yyyy-MM-dd HH:mm:ss\n serialization:\n # 格式化输出\n INDENT_OUTPUT: false\n # 忽略无法转换的对象\n fail_on_empty_beans: false\n deserialization:\n # 允许对象忽略json中不存在的属性\n fail_on_unknown_properties: false\n\n# feign 配置\nfeign:\n sentinel:\n enabled: true\n okhttp:\n enabled: true\n httpclient:\n enabled: false\n client:\n config:\n default:\n connectTimeout: 10000\n readTimeout: 10000\n compression:\n request:\n enabled: true\n response:\n enabled: true\n\n# 暴露监控端点\nmanagement:\n endpoints:\n web:\n exposure:\n include: \''*\''\n','760986157e62a0c1e0dadf9d2a6acf40','2019-11-29 16:31:20','2021-11-16 12:03:58','','0:0:0:0:0:0:0:1','','','通用配置','null','null','yaml','null'), +(1,'application-dev.yml','DEFAULT_GROUP','spring:\n main:\n allow-bean-definition-overriding: true\n autoconfigure:\n exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure\n # redis配置\n redis:\n timeout: 10s\n ssl: false\n #jackson配置\n jackson:\n # 日期格式化\n date-format: yyyy-MM-dd HH:mm:ss\n serialization:\n # 格式化输出\n INDENT_OUTPUT: false\n # 忽略无法转换的对象\n fail_on_empty_beans: false\n deserialization:\n # 允许对象忽略json中不存在的属性\n fail_on_unknown_properties: false\n# redisson 缓存配置\nredisson:\n cacheGroup:\n # 用例: @Cacheable(cacheNames=\"groupId\", key=\"#XXX\") 方可使用缓存组配置\n - groupId: redissonCacheMap\n # 组过期时间(脚本监控)\n ttl: 60000\n # 组最大空闲时间(脚本监控)\n maxIdleTime: 60000\n # 组最大长度\n maxSize: 0\n # 线程池数量\n threads: 16\n # Netty线程池数量\n nettyThreads: 32\n # 传输模式\n transportMode: \"NIO\"\n # 单节点配置\n singleServerConfig:\n # 客户端名称\n clientName: ${ruoyi.name}\n # 最小空闲连接数\n connectionMinimumIdleSize: 32\n # 连接池大小\n connectionPoolSize: 64\n # 连接空闲超时,单位:毫秒\n idleConnectionTimeout: 10000\n # 命令等待超时,单位:毫秒\n timeout: 3000\n # 如果尝试在此限制之内发送成功,则开始启用 timeout 计时。\n retryAttempts: 3\n # 命令重试发送时间间隔,单位:毫秒\n retryInterval: 1500\n # 发布和订阅连接的最小空闲连接数\n subscriptionConnectionMinimumIdleSize: 1\n # 发布和订阅连接池大小\n subscriptionConnectionPoolSize: 50\n # 单个连接最大订阅数量\n subscriptionsPerConnection: 5\n # DNS监测时间间隔,单位:毫秒\n dnsMonitoringInterval: 5000\n# feign 配置\nfeign:\n sentinel:\n enabled: true\n okhttp:\n enabled: true\n httpclient:\n enabled: false\n client:\n config:\n default:\n connectTimeout: 10000\n readTimeout: 10000\n compression:\n request:\n enabled: true\n response:\n enabled: true\n\n# 暴露监控端点\nmanagement:\n endpoints:\n web:\n exposure:\n include: \'*\'\n','760986157e62a0c1e0dadf9d2a6acf40','2019-11-29 16:31:20','2021-11-16 12:03:58','','0:0:0:0:0:0:0:1','','','通用配置','null','null','yaml','null'), (2,'ruoyi-gateway-dev.yml','DEFAULT_GROUP','spring:\n redis:\n host: localhost\n port: 6379\n password: \n cloud:\n gateway:\n discovery:\n locator:\n lowerCaseServiceId: true\n enabled: true\n routes:\n # 认证中心\n - id: ruoyi-auth\n uri: lb://ruoyi-auth\n predicates:\n - Path=/auth/**\n filters:\n # 验证码处理\n - CacheRequestFilter\n - ValidateCodeFilter\n - StripPrefix=1\n # 代码生成\n - id: ruoyi-gen\n uri: lb://ruoyi-gen\n predicates:\n - Path=/code/**\n filters:\n - StripPrefix=1\n # 定时任务\n - id: ruoyi-job\n uri: lb://ruoyi-job\n predicates:\n - Path=/schedule/**\n filters:\n - StripPrefix=1\n # 系统模块\n - id: ruoyi-system\n uri: lb://ruoyi-system\n predicates:\n - Path=/system/**\n filters:\n - StripPrefix=1\n # 文件服务\n - id: ruoyi-file\n uri: lb://ruoyi-file\n predicates:\n - Path=/file/**\n filters:\n - StripPrefix=1\n\n# 安全配置\nsecurity:\n # 验证码\n captcha:\n enabled: true\n type: math\n # 防止XSS攻击\n xss:\n enabled: true\n excludeUrls:\n - /system/notice\n # 不校验白名单\n ignore:\n whites:\n - /auth/logout\n - /auth/login\n - /auth/register\n - /*/v2/api-docs\n - /csrf\n','2f5a6b5a4ccf20b5801c5cf842456ec6','2020-05-14 14:17:55','2021-07-30 09:07:14',NULL,'0:0:0:0:0:0:0:1','','','网关模块','null','null','yaml','null'), (3,'ruoyi-auth-dev.yml','DEFAULT_GROUP','spring: \r\n redis:\r\n host: localhost\r\n port: 6379\r\n password: \r\n','b7354e1eb62c2d846d44a796d9ec6930','2020-11-20 00:00:00','2021-02-28 21:06:58',NULL,'0:0:0:0:0:0:0:1','','','认证中心','null','null','yaml','null'), (4,'ruoyi-monitor-dev.yml','DEFAULT_GROUP','# spring\r\nspring: \r\n security:\r\n user:\r\n name: ruoyi\r\n password: 123456\r\n boot:\r\n admin:\r\n ui:\r\n title: 若依服务状态监控\r\n','d8997d0707a2fd5d9fc4e8409da38129','2020-11-20 00:00:00','2020-12-21 16:28:07',NULL,'0:0:0:0:0:0:0:1','','','监控中心','null','null','yaml','null'),