Redis error connection reset in Spring Boot/Spring Cloud

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.

Guess you like

Origin blog.csdn.net/woshisangsang/article/details/108116387