上周在自己的项目中发现了一个问题,由于用户信息是在redis中缓存的,所以登录和聊天都需要从redis中获取到对应的用户信息。但是发现刚启动或者几分钟未访问后首次访问,都会报一个command timed out异常,然在后台能看到redis重新连接的日志,再进行访问就又正常了。通过baidu得到的结果,要么是把timeout设置成5000,要么是在抛异常的时候捕获到然后重新请求,但是经过我的验证都是无效的。
最终,我找到了适合自己的解决方法,分享给大家,希望能对大家有所帮助。
1、yml文件配置
spring:
redis:
jedis:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 10
# 连接池最大连接数(使用负值表示没有限制)
max-active: 10
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1
testOnBorrow: true
testWhileIdle: true
minEvictableIdleTimeMills: 60000
timeBetweenEvictionRunsMillis: 30000
numTestsPerEvictionRun: -1
# 连接超时时间(毫秒)
timeout: 5000
重点应该是testWhileIdle、minEvictableIdleTimeMills、timeBetweenEvictionRunsMillis、numTestsPerEvictionRun这四个属性
2、在RedisConfig中创建两个Bean,jedisPoolConfig和redisConnectionFactory
@Bean
public JedisPoolConfig jedisPoolConfig(){
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
jedisPoolConfig.setTestWhileIdle(testWhileIdle);
jedisPoolConfig.setTestOnBorrow(testOnBorrow);
jedisPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMills);
jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
jedisPoolConfig.setTestOnCreate(true);
jedisPoolConfig.setTestOnReturn(true);
return jedisPoolConfig;
}
@Bean
public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
//设置redis服务器的host或者ip地址
redisStandaloneConfiguration.setHostName(host);
redisStandaloneConfiguration.setPort(port);
//获得默认的连接池构造
//这里需要注意的是,edisConnectionFactoryJ对于Standalone模式的没有(RedisStandaloneConfiguration,JedisPoolConfig)的构造函数,对此
//我们用JedisClientConfiguration接口的builder方法实例化一个构造器,还得类型转换
JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcf = (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder();
//修改我们的连接池配置
jpcf.poolConfig(jedisPoolConfig);
//通过构造器来构造jedis客户端配置
JedisClientConfiguration jedisClientConfiguration = jpcf.build();
return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
}
3、获取yml文件中定义的属性
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.jedis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.jedis.pool.max-wait}")
private long maxWaitMillis;
@Value("${spring.redis.jedis.pool.testOnBorrow}")
private Boolean testOnBorrow;
@Value("${spring.redis.jedis.pool.testWhileIdle}")
private Boolean testWhileIdle;
@Value("${spring.redis.jedis.pool.minEvictableIdleTimeMills}")
private int minEvictableIdleTimeMills;
@Value("${spring.redis.jedis.pool.timeBetweenEvictionRunsMillis}")
private int timeBetweenEvictionRunsMillis;
@Value("${spring.redis.jedis.pool.numTestsPerEvictionRun}")
private int numTestsPerEvictionRun;
4、把factory给redisTemplate使用
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<Object, Object>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());//key序列化
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(Object.class)); //value序列化
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer(Object.class));
redisTemplate.setDefaultSerializer(new Jackson2JsonRedisSerializer(Object.class));
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
重点是前两步,后两步安装自己原来的代码改下就好了,希望能对大家有所帮助。
最后修改于 2019-01-01 11:27:33
如果觉得我的文章对你有用,请随意赞赏
扫一扫支付


2019-07-18 16:20:04