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

浙公网安备 33010602011771号