我在多线程环境中使用Spring Redis模板。一个线程将数据保存到Redis,另一个线程(调度程序)从中获取数据。 JedisConnectionFactory在Redis模板中使用。以下是用于获取redis连接的代码段:
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory jedisConnectionFactory = null;
try {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(hostName,
port);
jedisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration);
} catch (RedisConnectionFailureException e) {
LOGGER.error("Connection break with redis " + e.getMessage());
}
return jedisConnectionFactory;
}
/**
* Redis template.
*
* @return the redis template
*/
@Bean
public RedisTemplate<String, Object> redisTemplate() {
final RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(jedisConnectionFactory());
template.setValueSerializer(new GenericToStringSerializer<Object>(Object.class));
template.setEnableTransactionSupport(true);
return template;
}
redis模板的实例是使用构造函数自动装配获得的,如下所示:
@Autowired
public A(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
使用Redis模板的“ findAll()”方法从Redis提取数据时出现异常:
org.springframework.data.redis.RedisConnectionFailureException:java.net.SocketException:对等重置连接:套接字写入错误;嵌套的异常是redis.clients.jedis.exceptions.JedisConnectionException:java.net.SocketException:对等重置连接:套接字写入错误
以下是我的发现:
请建议使用“ JedisConnectionFactory”,“ RedisStandAloneConfiguration”和“ RedisTemplate”处理多线程的最佳方法。
答案 0 :(得分:0)
此问题的原因是:
Redis模板是线程安全的,但仅当它使用连接池时;如果未使用连接池,则同时进行的连接调用将导致来自(服务器/客户端)任一端的RST信号,因此将引发“对等连接重置”异常。因此,如果我们需要使用Redis模板,则创建一个连接池,并为池配置设置“ maxIdle”和“ maxTotal”。另外,请确保在任何情况下都不应该关闭系统(休眠)。
正常工作的代码:
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory jedisConnectionFactory = null;
try {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(hostName,
port);
jedisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration);
jedisConnectionFactory.getPoolConfig().setMaxTotal(50);
jedisConnectionFactory.getPoolConfig().setMaxIdle(50);
} catch (RedisConnectionFailureException e) {
e.getMessage();
}
return jedisConnectionFactory;
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
final RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(jedisConnectionFactory());
template.setValueSerializer(new GenericToStringSerializer<Object>(Object.class));
template.setEnableTransactionSupport(true);
return template;
}