0%

springboot自适应redis配置

说明

通过配置实现redis连接单机还是哨兵.

实现

  • application.yml
spring:
  redis:
    #  引入的自定义配置告知是使用单机还是哨兵:standalone / sentinel / cluster
    type: ${REDIS_TYPE:sentinel}
    port: ${REDIS_PORT:6379}
    host: ${REDIS_HOST:192.168.3.27}
    password: ${REDIS_PASSWORD}
    database: ${REDIS_DATABASE:8}
    sentinel:
      master: ${REDIS_SENTINEL_MASTER:mymaster}
      nodes: ${REDIS_SENTINEL_NODES:192.168.3.17:26379,192.168.3.19:26379,192.168.3.20:26379}
      password: ${REDIS_SENTINEL_PASSWORD}
  • RedisConfig.java
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.*;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * redis 配置
 */
@Configuration
@Slf4j
public class RedisConfig {
    @Value("${spring.redis.type}")
    private String type;
    @Autowired
    RedisProperties properties;

    @Bean
    public RedisTemplate<String, String> redisTemplate(@Autowired RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setKeySerializer(keySerializer());
        redisTemplate.setHashKeySerializer(keySerializer());
        redisTemplate.setValueSerializer(valueSerializer());
        redisTemplate.setHashValueSerializer(valueSerializer());
        return redisTemplate;
    }

    private RedisSerializer<String> keySerializer() {
        return new StringRedisSerializer();
    }

    //使用Jackson序列化器
    private StringRedisSerializer valueSerializer() {
        return new StringRedisSerializer();
    }

    // 根据配置的type创建RedisConnectionFactory
    @Bean
    public RedisConnectionFactory connectionFactory() throws Exception {
        switch (type) {
            case "standalone": {
                RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();
                redisConfig.setHostName(properties.getHost());
                redisConfig.setPort(properties.getPort());
                redisConfig.setPassword(properties.getPassword());
                redisConfig.setDatabase(properties.getDatabase());
                return new LettuceConnectionFactory(redisConfig);
            }
            case "sentinel": {
                RedisProperties.Sentinel sentinel = properties.getSentinel();
                RedisSentinelConfiguration redisConfig = new RedisSentinelConfiguration();
                redisConfig.master(sentinel.getMaster());
                redisConfig.setSentinelPassword(sentinel.getPassword());
                redisConfig.setDatabase(properties.getDatabase());
                for (String node : sentinel.getNodes()) {
                    String split[] = node.split(":");
                    redisConfig.addSentinel(new RedisNode(split[0], Integer.parseInt(split[1])));
                }
                return new LettuceConnectionFactory(redisConfig);
            }
            case "cluster": {
                // 集群的不常用,暂未实现,可以参考 https://www.zhuqiaolun.com/2020/11/1605606341401/1605606341401/ 实现
                RedisClusterConfiguration redisConfig = new RedisClusterConfiguration();
                throw new Exception("redis cluster config not support.");
            }
            default:
                throw new Exception("redis config type not support.");
        }
    }
}