哨兵模式下,使用redisTemplate
·
import java.util.Set;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
import static org.springframework.core.codec.StringDecoder.DEFAULT_CHARSET;
/**
* @author
* @date
*/
@Configuration
public class RedisDefaultConfig {
/**
* redis的连接池配置
*/
@Autowired
private JedisPoolConfig jedisPoolConfig;
/**
* redis密码
*/
@Value("${spring.redis.password}")
private String password;
/**
* 主节点名字
*/
@Value("${spring.redis.sentinel.master}")
private String master = "mymaster";
/**
* 哨兵节点配置,数据格式 127.0.0.1:26379,127.0.0.1:26380
*/
@Value("${spring.redis.sentinel.nodes}")
private String sentinelNodes;
/**
* redis哨兵连接池工厂
* 创建条件:
* 1、系统中没有任何RedisConnectionFactory对象
* 2、需要存在JedisPoolConfig连接池配置时,才会创建此对象
*
* @return 连接池工厂
*/
@Bean
@ConditionalOnMissingBean(RedisConnectionFactory.class)
@ConditionalOnClass(JedisPoolConfig.class)
@Order(-1)
public RedisConnectionFactory redisConnectionFactory() {
// 装配哨兵节点配置文件
if(StringUtils.isBlank(sentinelNodes)){
throw new RuntimeException("哨兵服务ip&port:不能为空");
}
Set<String> sentinels = Sets.newHashSet( StringUtils.split(sentinelNodes, ","));
// 哨兵专用配置类
RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration(master,sentinels);
// 设置redis密码
sentinelConfig.setPassword(password);
// 默认数据库为0
sentinelConfig.setDatabase(0);
return new JedisConnectionFactory(sentinelConfig, jedisPoolConfig);
}
/**
* 自定义的RedisTemplate,如果系统中没有RedisTemplate,则默认实现一个
* @param jedisConnectionFactory 缓存连接工厂类
* @return
*/
@Bean
@ConditionalOnMissingBean(RedisTemplate.class)
@Order(-1)
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory jedisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 配置连接工厂
template.setConnectionFactory(jedisConnectionFactory);
//使用FastJsonRedisSerializer 来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
// 值采用json序列化
template.setValueSerializer(fastJsonRedisSerializer);
//使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
// 设置hash key 和value序列化模式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(fastJsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
/**
* 自定义Redis的连接池配置文件
* @param maxTotal jedis最大分配对象
* @param maxIdle 最大保存idel状态对象数
* @param maxWaitMillis jedis池没有对象返回时,最大等待时间
* @param testOnBorrow
* @param testOnReturn
* @param blockWhenExhausted 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
* @param testWhileIdle Idle时进行连接扫描
* @param timeBetweenEvictionRunsMillis 表示idle object evitor两次扫描之间要sleep的毫秒数
* @param numTestsPerEvictionRun 表示idle object evitor每次扫描的最多的对象数
* @param minEvictableIdleTimeMillis 表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
* @return redis连接池配置类
*/
@Bean
@ConditionalOnMissingBean(JedisPoolConfig.class)
@Order(-1)
public JedisPoolConfig jedisPoolConfig(@Value("${spring.redis.jedis.pool.maxTotal}") int maxTotal,
@Value("${spring.redis.jedis.pool.maxIdle}") int maxIdle,
@Value("${spring.redis.jedis.pool.maxWaitMillis}") int maxWaitMillis,
@Value("${spring.redis.jedis.pool.testOnBorrow}") boolean testOnBorrow,
@Value("${spring.redis.jedis.pool.testOnReturn}") boolean testOnReturn,
@Value("${spring.redis.jedis.pool.blockWhenExhausted}") boolean blockWhenExhausted,
@Value("${spring.redis.jedis.pool.testWhileIdle}") boolean testWhileIdle,
@Value("${spring.redis.jedis.pool.timeBetweenEvictionRunsMillis}") long timeBetweenEvictionRunsMillis,
@Value("${spring.redis.jedis.pool.numTestsPerEvictionRun}") int numTestsPerEvictionRun,
@Value("${spring.redis.jedis.pool.minEvictableIdleTimeMillis}") long minEvictableIdleTimeMillis) {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(maxTotal);
config.setMaxIdle(maxIdle);
config.setMaxWaitMillis(maxWaitMillis);
config.setTestOnBorrow(testOnBorrow);
config.setTestOnReturn(testOnReturn);
config.setBlockWhenExhausted(blockWhenExhausted);
config.setTestWhileIdle(testWhileIdle);
config.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
config.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
config.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
return config;
}
class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
private Class<T> clazz;
public FastJsonRedisSerializer(Class<T> 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);
}
}
}
spring:
redis:
jedis:
pool:
#jedis最大分配对象
maxTotal: 1024
#jedis最大保存idel状态对象数
maxIdle: 200
#jedis池没有对象返回时,最大等待时间
maxWaitMillis: 10000
# 若testOnBorrow属性设置为true,从连接池中获取对象时,会进行检查,检查不通过,会从连接池中移走并销毁。
testOnBorrow: false
# 若testOnReturn属性设置为true,归还连接时,会进行检查,检查不通过,销毁。
testOnReturn: false
blockWhenExhausted: false
#空闲时进行连接扫描
testWhileIdle: true
#表示idle object evitor两次扫描之间要sleep的毫秒数
timeBetweenEvictionRunsMillis: 30000
#表示idle object evitor每次扫描的最多的对象数
numTestsPerEvictionRun: 10
#表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
minEvictableIdleTimeMillis: 60000
更多推荐


所有评论(0)