1. Phenomenon
The Spring Cloud project, using JRedis connection pool, often find error messages in the log as follows:
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Connection reset
at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:202)
at redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40)
at redis.clients.jedis.Protocol.process(Protocol.java:153)
at redis.clients.jedis.Protocol.read(Protocol.java:218)
at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:341)
at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:240)
at redis.clients.jedis.BinaryJedis.quit(BinaryJedis.java:256)
at org.springframework.data.redis.connection.jedis.JedisConnection.close(JedisConnection.java:298)
... 38 common frames omitted
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:196)
Connection reset means that the connection is reset. The specific meaning is that the server has closed the Connection for some reason. This must be related to the number of connections and timeout period.
2. Ideas
Searching for relevant information online, I learned that it is not safe for JRedis to share an instance in a multi-threaded situation, so it is a big hidden danger. And JRedis can't support more connections.
So the problem should be the connection pool. JRedis is a time bomb in the case of multi-threading and high concurrency. If it is so, just replace it.
Continue to inquire about the information and find Lettuce based on Netty. I feel relieved when I see Netty. Some experienced programmers know it is an excellent salt with high performance and high concurrency.
3. Realization
First introduce related dependencies:
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- lettuce pool 缓存连接池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
Then configure the connection parameters:
spring:
# redis配置信息
redis:
# redis数据库索引(默认为0)
database: 0
# redis服务器地址
host: 192.168.20.214
# redis服务器连接端口
port: 6379
password:
lettuce:
pool:
max-total: 100
max-active: 100
max-wait: 1000
max-idle: 20
min-idle: 0
Finally use the configuration class:
/**
* redis配置类
*/
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
// 连接工厂
template.setConnectionFactory(factory);
// 使用Jackson2JsonRedisSerializer
Jackson2JsonRedisSerializer<Object> jacksonSeial = new Jackson2JsonRedisSerializer<Object>(Object.class);
ObjectMapper om = new ObjectMapper();
// 指定要序列化的域
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jacksonSeial.setObjectMapper(om);
// 值采用json序列化
template.setValueSerializer(jacksonSeial);
// 使用StringRedisSerializer
template.setKeySerializer(new StringRedisSerializer());
// 设置hash序列化模式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(jacksonSeial);
template.afterPropertiesSet();
return template;
}
}
4. Experiment
Restart the project after the modification and find it is relatively stable. If you have any subsequent questions, please give feedback.