|
|
@@ -0,0 +1,170 @@
|
|
|
+package cn.reghao.tnb.admin.config;
|
|
|
+
|
|
|
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
|
|
+import com.fasterxml.jackson.annotation.PropertyAccessor;
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
+import io.lettuce.core.ReadFrom;
|
|
|
+import io.lettuce.core.resource.DefaultClientResources;
|
|
|
+import jakarta.annotation.PreDestroy;
|
|
|
+import jakarta.annotation.Resource;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
|
|
+import org.springframework.beans.factory.annotation.Qualifier;
|
|
|
+import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
|
|
|
+import org.springframework.context.annotation.Bean;
|
|
|
+import org.springframework.context.annotation.Configuration;
|
|
|
+import org.springframework.data.redis.connection.RedisConnectionFactory;
|
|
|
+import org.springframework.data.redis.connection.RedisPassword;
|
|
|
+import org.springframework.data.redis.connection.RedisSentinelConfiguration;
|
|
|
+import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
|
|
+import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
|
|
|
+import org.springframework.data.redis.core.RedisTemplate;
|
|
|
+import org.springframework.data.redis.core.StringRedisTemplate;
|
|
|
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
|
|
+import org.springframework.data.redis.serializer.StringRedisSerializer;
|
|
|
+
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.List;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author reghao
|
|
|
+ * @date 2026-01-23 14:25:52
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+//@Configuration
|
|
|
+public class RedisConfig {
|
|
|
+ @Resource
|
|
|
+ private RedisProperties redisProperties;
|
|
|
+ private DefaultClientResources clientResources;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建commonsPool配置
|
|
|
+ *
|
|
|
+ * @return .
|
|
|
+ */
|
|
|
+ @Bean
|
|
|
+ public GenericObjectPoolConfig<?> genericObjectPoolConfig() {
|
|
|
+ GenericObjectPoolConfig<?> config = new GenericObjectPoolConfig<>();
|
|
|
+ config.setMinIdle(redisProperties.getLettuce().getPool().getMinIdle());
|
|
|
+ config.setMaxIdle(redisProperties.getLettuce().getPool().getMaxIdle());
|
|
|
+ config.setMaxTotal(redisProperties.getLettuce().getPool().getMaxActive());
|
|
|
+ config.setMaxWait(redisProperties.getLettuce().getPool().getMaxWait());
|
|
|
+ return config;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建RedisSentinel配置
|
|
|
+ *
|
|
|
+ * @return .
|
|
|
+ */
|
|
|
+ @Bean
|
|
|
+ public RedisSentinelConfiguration sentinelConfiguration() {
|
|
|
+ List<String> nodeList = redisProperties.getSentinel().getNodes();
|
|
|
+ RedisSentinelConfiguration redisSentinelConfiguration =
|
|
|
+ new RedisSentinelConfiguration(redisProperties.getSentinel().getMaster(), new HashSet<>(nodeList));
|
|
|
+ // 主节点密码
|
|
|
+ redisSentinelConfiguration.setPassword(RedisPassword.of(redisProperties.getPassword()));
|
|
|
+ // 哨兵密码
|
|
|
+ redisSentinelConfiguration.setSentinelPassword(RedisPassword.of(redisProperties.getSentinel().getPassword().toCharArray()));
|
|
|
+ return redisSentinelConfiguration;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建lettuce连接池
|
|
|
+ *
|
|
|
+ * @param genericObjectPoolConfig .
|
|
|
+ * @param sentinelConfiguration .
|
|
|
+ * @return .
|
|
|
+ */
|
|
|
+ @Bean
|
|
|
+ public RedisConnectionFactory lettuceConnectionFactory(GenericObjectPoolConfig<?> genericObjectPoolConfig,
|
|
|
+ RedisSentinelConfiguration sentinelConfiguration) {
|
|
|
+ // 声明资源
|
|
|
+ this.clientResources = DefaultClientResources.create();
|
|
|
+
|
|
|
+ // 构建lettuce配置
|
|
|
+ LettucePoolingClientConfiguration lettuceClientConfiguration =
|
|
|
+ LettucePoolingClientConfiguration.builder()
|
|
|
+ .poolConfig(genericObjectPoolConfig)
|
|
|
+ .readFrom(ReadFrom.REPLICA)
|
|
|
+ .clientResources(clientResources)
|
|
|
+ .build();
|
|
|
+
|
|
|
+ // 构建lettuce连接池
|
|
|
+ LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(sentinelConfiguration, lettuceClientConfiguration);
|
|
|
+ // 每次获取连接时验证连接的有效性(注意性能影响)
|
|
|
+ lettuceConnectionFactory.setValidateConnection(true);
|
|
|
+ // 手动触发连接池初始化
|
|
|
+ lettuceConnectionFactory.afterPropertiesSet();
|
|
|
+
|
|
|
+ log.info("connected to redis sentinel,node info: {}", sentinelConfiguration.getSentinels());
|
|
|
+ return lettuceConnectionFactory;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 应用关闭时触发
|
|
|
+ */
|
|
|
+ @PreDestroy
|
|
|
+ public void shutdown() {
|
|
|
+ if (null != clientResources) {
|
|
|
+ clientResources.shutdown(100, 100, TimeUnit.MILLISECONDS);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 1.使用自定义lettuce连接池
|
|
|
+ * 2.声明序列化方式
|
|
|
+ *
|
|
|
+ * @param connectionFactory .
|
|
|
+ * @return .
|
|
|
+ */
|
|
|
+ @Bean
|
|
|
+ @SuppressWarnings("all")
|
|
|
+ public RedisTemplate<String, Object> redisTemplate(@Qualifier("lettuceConnectionFactory") RedisConnectionFactory connectionFactory) {
|
|
|
+ RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
|
|
+ redisTemplate.setConnectionFactory(connectionFactory);
|
|
|
+
|
|
|
+ // 配置String的序列化
|
|
|
+ StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
|
|
|
+
|
|
|
+ // 配置Json的序列化
|
|
|
+ Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
|
|
|
+ ObjectMapper objectMapper = new ObjectMapper();
|
|
|
+ objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
|
|
+ objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
|
|
+ jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
|
|
|
+
|
|
|
+ // Key采用String的序列化方式
|
|
|
+ redisTemplate.setKeySerializer(stringRedisSerializer);
|
|
|
+ // Hash的key也采用String的序列化方式
|
|
|
+ redisTemplate.setHashKeySerializer(stringRedisSerializer);
|
|
|
+ // Value序列化方式采用jackson
|
|
|
+ redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
|
|
|
+ // Hash的value序列化方式采用jackson
|
|
|
+ redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
|
|
|
+
|
|
|
+ redisTemplate.afterPropertiesSet();
|
|
|
+ return redisTemplate;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 1.使用自定义lettuce连接池
|
|
|
+ * 2.声明序列化方式
|
|
|
+ *
|
|
|
+ * @param connectionFactory .
|
|
|
+ * @return .
|
|
|
+ */
|
|
|
+ @Bean
|
|
|
+ public StringRedisTemplate stringRedisTemplate(@Qualifier("lettuceConnectionFactory") RedisConnectionFactory connectionFactory) {
|
|
|
+ StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
|
|
|
+ StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
|
|
|
+
|
|
|
+ stringRedisTemplate.setConnectionFactory(connectionFactory);
|
|
|
+ stringRedisTemplate.setKeySerializer(stringRedisSerializer);
|
|
|
+ stringRedisTemplate.setValueSerializer(stringRedisSerializer);
|
|
|
+
|
|
|
+ stringRedisTemplate.afterPropertiesSet();
|
|
|
+ return stringRedisTemplate;
|
|
|
+ }
|
|
|
+}
|