Spring Boot/Spring Cloud中Redis报错Connection reset

1. 现象

Spring Cloud项目,使用的JRedis连接池,日志里面经常会发现报错信息如下:

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表示连接被重置,具体含义是服务器端因为某些原因关闭了Connection,这肯定是跟连接的数量、超时时间等相关。

2. 思路

网上查询相关资料,了解到JRedis在多线程情况下共享一个实例是不安全的,所以是一个很大的隐患。而且JRedis也不能较好的支持较多的连接数。

所以问题应该是出在连接池上,JRedis在多线程高并发的情况下,是一个定时炸弹,竟然如此,换掉就是了。

继续查询资料,找到了基于Netty的Lettuce,看到Netty就放心了,有点资历的程序猿都知道是高性能高并发的绝佳带盐。

3. 实现

首先引入相关依赖:

	<!-- 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>

然后配置连接参数:

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

最后使用配置类:

/**
 * 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. 实验

修改后重新启动项目,发现比较稳定,后续有问题再反馈吧。

已标记关键词 清除标记
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Connection reset org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:659) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552) javax.servlet.http.HttpServlet.service(HttpServlet.java:621) javax.servlet.http.HttpServlet.service(HttpServlet.java:722) org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) root cause redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Connection reset redis.clients.jedis.Protocol.process(Protocol.java:79) redis.clients.jedis.Protocol.read(Protocol.java:131) redis.clients.jedis.Connection.getBinaryBulkReply(Connection.java:182) redis.clients.jedis.Connection.getBulkReply(Connection.java:171) redis.clients.jedis.Jedis.get(Jedis.java:67) com.shakecheck.service.RedisService.get(RedisService.java:79) com.shakecheck.controller.HCountController.Homecount(HCountController.java:53) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) java.lang.reflect.Method.invoke(Unknown Source) org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:710) org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:167) org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:414) org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:402) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552) javax.servlet.http.HttpServlet.service(HttpServlet.java:621) javax.servlet.http.HttpServlet.service(HttpServlet.java:722) org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) root cause java.net.SocketException: Connection reset java.net.SocketInputStream.read(Unknown Source) java.net.SocketInputStream.read(Unknown Source) java.net.SocketInputStream.read(Unknown Source) redis.clients.util.RedisInputStream.fill(RedisInputStream.java:109) redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:45) redis.clients.jedis.Protocol.process(Protocol.java:64) redis.clients.jedis.Protocol.read(Protocol.java:131) redis.clients.jedis.Connection.getBinaryBulkReply(Connection.java:182) redis.clients.jedis.Connection.getBulkReply(Connection.java:171) redis.clients.jedis.Jedis.get(Jedis.java:67) com.shakecheck.service.RedisService.get(RedisService.java:79) com.shakecheck.controller.HCountController.Homecount(HCountController.java:53) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) java.lang.reflect.Method.invoke(Unknown Source) org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:710) org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:167) org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:414) org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:402) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552) javax.servlet.http.HttpServlet.service(HttpServlet.java:621) javax.servlet.http.HttpServlet.service(HttpServlet.java:722) org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
©️2020 CSDN 皮肤主题: 点我我会动 设计师:上身试试 返回首页