RedisTemplate自适应Redis配置模式config

RedisTemplate配置Java源码:

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.*;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.StringUtils;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisPoolConfig;

import java.util.LinkedHashSet;
import java.util.Set;

/**
 * 自适应Redis配置模式config
 */
@Slf4j
@Configuration
@EnableCaching
public class RedisTemplateConfig extends CachingConfigurerSupport {
    @Value("${spring.redis.host:}")
    private String node;
    @Value("${spring.redis.timeout:0}")
    private int timeout;
    @Value("${spring.redis.password:}")
    private String password;
    @Value("${spring.redis.sentinel.nodes:}")
    private String sentinel;
    @Value("${spring.redis.sentinel.master:}")
    private String master;
    @Value("${spring.redis.database:0}")
    private Integer database;

    @Value("${spring.redis.jedis.pool.max-total:8}")
    private int maxTotal;
    @Value("${spring.redis.jedis.pool.max-idle:8}")
    private int maxIdle;
    @Value("${spring.redis.jedis.pool.min-idle:0}")
    private int minIdle;
    @Value("${spring.redis.jedis.pool.max-wait:-1}")
    private long maxWaitMillis;
    @Value("${spring.redis.jedis.pool.test-on-borrow:true}")
    private boolean testOnBorrow;
    @Value("${spring.redis.jedis.factory.max-redirects:5}")
    private int maxRedirect;
    @Autowired
    private JedisPoolConfig jedisPoolConfig;
    @Autowired
    private JedisConnectionFactory jedisConnectionFactory;

    @Bean
    @ConditionalOnMissingBean
    @Override
    public CacheManager cacheManager() {
        // 初始化缓存管理器,在这里我们可以缓存的整体过期时间什么的,我这里默认没有配置
        log.info("初始化 -> [{}]", "CacheManager RedisCacheManager Start");
        RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager
                .RedisCacheManagerBuilder
                .fromConnectionFactory(jedisConnectionFactory);
        return builder.build();
    }

    @Bean
    @ConditionalOnMissingBean
    @Override
    public CacheErrorHandler errorHandler() {
        // 异常处理,当Redis发生异常时,打印日志,但是程序正常走
        log.info("初始化 -> [{}]", "Redis CacheErrorHandler");
        return new CacheErrorHandler() {
            @Override
            public void handleCacheGetError(RuntimeException e, Cache cache, Object key) {
                log.error("Redis occur handleCacheGetError:key -> [{}]", key, e);
            }

            @Override
            public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) {
                log.error("Redis occur handleCachePutError:key -> [{}];value -> [{}]", key, value, e);
            }

            @Override
            public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) {
                log.error("Redis occur handleCacheEvictError:key -> [{}]", key, e);
            }

            @Override
            public void handleCacheClearError(RuntimeException e, Cache cache) {
                log.error("Redis occur handleCacheClearError:", e);
            }
        };
    }

    @Bean
    @ConditionalOnMissingBean
    public JedisPoolConfig jedisPoolConfig() {
        JedisPoolConfig config = new JedisPoolConfig();
        // 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1
        config.setMaxWaitMillis(maxWaitMillis);
        //最小空闲连接数, 默认0
        config.setMinIdle(minIdle);
        //最大空闲连接数, 默认8个
        config.setMaxIdle(maxIdle);
        //最大连接数, 默认值8个
        config.setMaxTotal(maxTotal);
        //对拿到的connection进行validateObject校验
        config.setTestOnBorrow(testOnBorrow);
        return config;
    }

    @Bean
    @ConditionalOnMissingBean
    public JedisConnectionFactory jedisConnectionFactory() {
        JedisConnectionFactory factory = null;

        Set<HostAndPort> nodes = new LinkedHashSet<>();
        if(!StringUtils.isEmpty(node)) {
            String[] split = node.split(",");
            for (String s : split) {
                try {
                    String[] split1 = s.split(":");
                    nodes.add(new HostAndPort(split1[0], Integer.parseInt(split1[1])));
                } catch (Exception e) {
                    throw new RuntimeException(String.format("出现配置错误!请确认node=[%s]是否正确", node));
                }
            }
        }


        //获得默认的连接池构造器
        JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcb =
                (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder();
        //指定jedisPoolConifig来修改默认的连接池构造器
        jpcb.poolConfig(jedisPoolConfig);
        //通过构造器来构造jedis客户端配置
        JedisClientConfiguration jedisClientConfiguration = jpcb.build();
        //如果是哨兵的模式
        if (!StringUtils.isEmpty(sentinel)) {
            log.info("Redis use SentinelConfiguration");
            RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration();
            String[] sentinelArray = sentinel.split(",");
            for (String s : sentinelArray) {
                try {
                    String[] split1 = s.split(":");
                    redisSentinelConfiguration.addSentinel(new RedisNode(split1[0], Integer.parseInt(split1[1])));
                } catch (Exception e) {
                    throw new RuntimeException(String.format("出现配置错误!请确认node=[%s]是否正确", node));
                }
            }
            redisSentinelConfiguration.setPassword(password);
            redisSentinelConfiguration.setMaster(master);
            redisSentinelConfiguration.setDatabase(database);
            factory = new JedisConnectionFactory(redisSentinelConfiguration, jedisClientConfiguration);
        }
        //如果是单个节点 用Standalone模式
        else if (nodes.size() == 1) {
            log.info("Redis use RedisStandaloneConfiguration");
            for (HostAndPort n : nodes) {
                RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
                if (!StringUtils.isEmpty(password)) {
                    redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
                }
                redisStandaloneConfiguration.setPort(n.getPort());
                redisStandaloneConfiguration.setHostName(n.getHost());
                redisStandaloneConfiguration.setDatabase(database);
                factory = new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
            }
        }
        //集群配置信息实现
        else {
            log.info("Redis use RedisStandaloneConfiguration");
            RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
            nodes.forEach(n -> {
                redisClusterConfiguration.addClusterNode(new RedisNode(n.getHost(), n.getPort()));
            });
            if (!StringUtils.isEmpty(password)) {
                redisClusterConfiguration.setPassword(RedisPassword.of(password));
            }
            redisClusterConfiguration.setMaxRedirects(maxRedirect);
            factory = new JedisConnectionFactory(redisClusterConfiguration, jedisClientConfiguration);
        }
        return factory;
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<String, Object> redisTemplate(JedisConnectionFactory jedisConnectionFactory) {
        //设置序列化
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置redisTemplate
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(jedisConnectionFactory);
        RedisSerializer<String> stringSerializer = new StringRedisSerializer();
        // key序列化
        redisTemplate.setKeySerializer(stringSerializer);
        // value序列化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        // Hash key序列化
        redisTemplate.setHashKeySerializer(stringSerializer);
        // Hash value序列化
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

  

application.properties配置:

spring.redis.sentinel.master=mymaster
spring.redis.sentinel.nodes=10.108.3.86:26379,10.108.3.186:26379,10.108.3.187:26379
spring.redis.password=vm-ubunut-sentinel
spring.redis.database=0
spring.redis.timeout=1000
spring.redis.client-type=jedis
#最大连接数, 默认值8个
spring.redis.jedis.pool.max-total=8
#最大空闲连接数, 默认8个
spring.redis.jedis.pool.max-idle=8
#最小空闲连接数, 默认0
spring.redis.jedis.pool.min-idle=0
#获取连接时的最大等待毫秒数,如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1
spring.redis.jedis.pool.max-wait=-1
#对拿到的connection进行validateObject校验
spring.redis.jedis.pool.test-on-borrow=true
#集群时最大重定向个数默认5
spring.redis.jedis.factory.max-redirects=5

以上spring.redis.sentinel.nodes是我配置的局域网redis哨兵,有兴趣可移步查看:https://www.cnblogs.com/huyueping/p/16851934.html

posted @ 2022-11-02 18:38  追你追到  阅读(116)  评论(0编辑  收藏  举报