Spring Boot使用Redis的Lettuce连接池,隔一段时间再连接就报连接超时

QQ914237918 2019-04-13 04:45:08
问题详细解说:
问题是这样的 ,任何时间只要连接上了, 就能正常的连接,但是呢,空闲下来隔十来分钟后再连接就会出现超时的现象了。。这个说到连接池的问题了,分析是这样的
假设服务端没有问题,配置没有问题。那就是SpringBoot的Redis的Lettuce出了问题, 没有空闲连接,当连接上来之后,一切正常,隔一段时间没有连接的时候,就会Spring就瘵连接池关了连接切断了,然后页面再一次请求连接的时候,客户端再重新请求连接到服务器。所以才会出现 这样的问题。才会出现 连接超时,
之后呢,再一次请求连接,超时之后过十几秒之后,又能重新连接上了,只要一直不间断 的连接是没有问题的,问题是一停下来没有连接的时候过十多分钟连接才会出现这个连接超时的现象,
不知道大神会有没有出现 这样的问题呢,我现在郁闷死了,我所有的连接都是基于Redis的。。所以当这个用不了的时候基本上服务启动不了了。。
这个问题困扰了好几天了,找了几百个博客说超时的的现象是那个timeout: 1000ms这个的问题,其实我测试过就算我这里超时时间加大到一万秒也是这样超时的,。原因不是刚刚开始的时候连接不上,而是空闲下来隔一段时间后,Spring回收了或是关闭了Lettuce的连接池引起的。。。
希望有大神站出来的指导一下,谢谢!~

使用环境说明:java11版本,springBoot2.11, 我是redis直接安装到服务器上了,服务器版本是CentOS7,Redis是5.04版本。连接使用的时候是本地开发连接测试的。

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<spring-cloud.version>Greenwich.RC2</spring-cloud.version>


开发环境IDEA2018.2,
贴出配置

redis:
host: 服务器地址
password: 密码
database: 0
port: 端口
lettuce:
pool:
max-active: 20
max-wait: -1ms
max-idle: 10
min-idle: 2
timeout: 1000ms


pom
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>


配置类
@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig {


@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuce) {
//设置序列化
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置redisTemplate
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(lettuce);
RedisSerializer<String> stringSerializer = new StringRedisSerializer();
// key序列化
redisTemplate.setKeySerializer(stringSerializer);
// value序列化
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// Hash key序列化
redisTemplate.setHashKeySerializer(stringSerializer);
// Hash value序列化
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
...全文
27768 61 打赏 收藏 转发到动态 举报
写回复
用AI写文章
61 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_27043521 2021-11-09
  • 打赏
  • 举报
回复

lettuceConnectionFactory.setValidateConnection(true); 通过设置连接校验,会在连接断开时重连,这样可以彻底解决超时问题

hotel2016 2021-09-08
  • 打赏
  • 举报
回复 4

这个问题应该是项目用了k8s做docker容器化部署,但是k8s有设置空闲连接超时就断开,所以当你从连接池拿到被断开的连接时就会报错,SpringBoot2.0之后有一个配置项可以解决这个问题。

    # 解决redis 240秒超时问题
    lettuce:
      cluster:
        refresh:
          adaptive: true
          period: 20

https://www.cnblogs.com/shouyaya/p/14607270.html

qq_25866555 2021-07-15
  • 打赏
  • 举报
回复 1

解决方案:lettuce提供了校验连接的方法,lettuce提供了校验连接的方法 只是默认没开启 开启的话是每次获取连接都会校验。可以定时校验来解决 或者开启获取连接的校验
1.定时校验来解决
/**

  • 每隔2秒校验异常lettuce连接是否正常,解决长期空闲lettuce连接关闭但是netty不能及时监控到的问题
  • @author hujun
  • /
    @Component
    @Slf4j
    public class LettuceConnectionValidTask {
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;
@Scheduled(cron="0/2 * * * * ?")
public void task() {
    if(redisConnectionFactory instanceof LettuceConnectionFactory){
        LettuceConnectionFactory c=(LettuceConnectionFactory)redisConnectionFactory;
        c.validateConnection();
    }
}

}

2.开启获取连接的校验
@Component
@Slf4j
public class LettuceConnectionValidConfig implements InitializingBean {
@Autowired
private RedisConnectionFactory redisConnectionFactory;

@Override
public void afterPropertiesSet() throws Exception {
    if(redisConnectionFactory instanceof LettuceConnectionFactory){
        LettuceConnectionFactory c=(LettuceConnectionFactory)redisConnectionFactory;
        c.setValidateConnection(true);
    }
}

}

暴走的大猩猩 2021-04-25
  • 打赏
  • 举报
回复
解决了吗,如何解决~
qq_25866555 2021-07-15
  • 举报
回复
@暴走的大猩猩 解决方案:lettuce提供了校验连接的方法,lettuce提供了校验连接的方法 只是默认没开启 开启的话是每次获取连接都会校验。可以定时校验来解决 或者开启获取连接的校验 1.定时校验来解决 /** * 每隔2秒校验异常lettuce连接是否正常,解决长期空闲lettuce连接关闭但是netty不能及时监控到的问题 * @author hujun */ @Component @Slf4j public class LettuceConnectionValidTask { @Autowired private RedisConnectionFactory redisConnectionFactory; @Scheduled(cron="0/2 * * * * ?") public void task() { if(redisConnectionFactory instanceof LettuceConnectionFactory){ LettuceConnectionFactory c=(LettuceConnectionFactory)redisConnectionFactory; c.validateConnection(); } } } 2.开启获取连接的校验 @Component @Slf4j public class LettuceConnectionValidConfig implements InitializingBean { @Autowired private RedisConnectionFactory redisConnectionFactory; @Override public void afterPropertiesSet() throws Exception { if(redisConnectionFactory instanceof LettuceConnectionFactory){ LettuceConnectionFactory c=(LettuceConnectionFactory)redisConnectionFactory; c.setValidateConnection(true); } } }
江南孤鹜 2021-01-24
  • 打赏
  • 举报
回复 1
引用 63 楼 打死再睡觉 的回复:
我用定时任务每30秒set一个值保持连接,勉强算是解决了
我试了几天各种方法,也没解决。也是跟你一样,想用你这种方案,但是总感觉不完美。
打死再睡觉 2021-01-18
  • 打赏
  • 举报
回复
我用定时任务每30秒set一个值保持连接,勉强算是解决了
逆小雨 2020-12-23
  • 打赏
  • 举报
回复
我也是一样,springboot2. 4 linux docker布署的redis5版本……几个月了都没解决
qq_25866555 2021-07-15
  • 举报
回复
@逆小雨 解决方案:lettuce提供了校验连接的方法,lettuce提供了校验连接的方法 只是默认没开启 开启的话是每次获取连接都会校验。可以定时校验来解决 或者开启获取连接的校验 1.定时校验来解决 /** * 每隔2秒校验异常lettuce连接是否正常,解决长期空闲lettuce连接关闭但是netty不能及时监控到的问题 * @author hujun */ @Component @Slf4j public class LettuceConnectionValidTask { @Autowired private RedisConnectionFactory redisConnectionFactory; @Scheduled(cron="0/2 * * * * ?") public void task() { if(redisConnectionFactory instanceof LettuceConnectionFactory){ LettuceConnectionFactory c=(LettuceConnectionFactory)redisConnectionFactory; c.validateConnection(); } } } 2.开启获取连接的校验 @Component @Slf4j public class LettuceConnectionValidConfig implements InitializingBean { @Autowired private RedisConnectionFactory redisConnectionFactory; @Override public void afterPropertiesSet() throws Exception { if(redisConnectionFactory instanceof LettuceConnectionFactory){ LettuceConnectionFactory c=(LettuceConnectionFactory)redisConnectionFactory; c.setValidateConnection(true); } } }
QQ914237918 2020-11-25
  • 打赏
  • 举报
回复
引用 59 楼 weixin_41678470 的回复:
[quote=引用 58 楼 u010637892 的回复:][quote=引用 33 楼 weixin_41678470 的回复:]这个问题我们在项目中遇到同样的问题,目前已经解决了。最终得到的答案是: 服务器不稳定造成的。
您可以尝试这样解决:
1.推荐使用生产环境的服务器,并且将redis 绑定生产环境的ip;因为云服务器的ip 地址是很稳定的,而本地服务的ip地址经常是变动的;经
过测试,这种每过10分就会重新请求连接,还会发生重试失败的情况,就是因为服务器不稳定造成的;
2.如果你在生产环境中,使用docker 部署,建议 不要在docker容器中 安装redis; 因为docker 容器 默认分配的ip 地址,也可能是变化的;
您可以直接将redis 安装在 服务器目录下,即可;
你说的不稳定是ip地址会变动吗?ip地址变了客户端肯定连不上了。[/quote]该问题描述的是,redis服务会间歇性的每隔10分钟就不断重试重连,所以,跟用生菜还是jedis连接池无关,一般springboot的启动包,都有自动配置,怎么配置一般都不会有问题。但是,我曾经尝试用docker来安装redis服务的时候,就出现了这种断连重试的情况。后来我改成直接在服务上安装,就不会再出现问题了。[/quote]

认同你的观点
高雪衣 2020-11-25
  • 打赏
  • 举报
回复
简单,啥也别配,只保留一个host 、url,保证不出问题
u010637892 2020-10-29
  • 打赏
  • 举报
回复
引用 33 楼 weixin_41678470 的回复:
这个问题我们在项目中遇到同样的问题,目前已经解决了。最终得到的答案是: 服务器不稳定造成的。 您可以尝试这样解决: 1.推荐使用生产环境的服务器,并且将redis 绑定生产环境的ip;因为云服务器的ip 地址是很稳定的,而本地服务的ip地址经常是变动的;经 过测试,这种每过10分就会重新请求连接,还会发生重试失败的情况,就是因为服务器不稳定造成的; 2.如果你在生产环境中,使用docker 部署,建议 不要在docker容器中 安装redis; 因为docker 容器 默认分配的ip 地址,也可能是变化的; 您可以直接将redis 安装在 服务器目录下,即可;
你说的不稳定是ip地址会变动吗?ip地址变了客户端肯定连不上了。
weixin_41678470 2020-10-29
  • 打赏
  • 举报
回复
引用 58 楼 u010637892 的回复:
[quote=引用 33 楼 weixin_41678470 的回复:]这个问题我们在项目中遇到同样的问题,目前已经解决了。最终得到的答案是: 服务器不稳定造成的。 您可以尝试这样解决: 1.推荐使用生产环境的服务器,并且将redis 绑定生产环境的ip;因为云服务器的ip 地址是很稳定的,而本地服务的ip地址经常是变动的;经 过测试,这种每过10分就会重新请求连接,还会发生重试失败的情况,就是因为服务器不稳定造成的; 2.如果你在生产环境中,使用docker 部署,建议 不要在docker容器中 安装redis; 因为docker 容器 默认分配的ip 地址,也可能是变化的; 您可以直接将redis 安装在 服务器目录下,即可;
你说的不稳定是ip地址会变动吗?ip地址变了客户端肯定连不上了。[/quote]该问题描述的是,redis服务会间歇性的每隔10分钟就不断重试重连,所以,跟用生菜还是jedis连接池无关,一般springboot的启动包,都有自动配置,怎么配置一般都不会有问题。但是,我曾经尝试用docker来安装redis服务的时候,就出现了这种断连重试的情况。后来我改成直接在服务上安装,就不会再出现问题了。
weixin_41678470 2020-10-27
  • 打赏
  • 举报
回复
引用 48 楼 justmemyselfand!zzz 的回复:
我就服这种楼主,别人讨论回复了几个月,最后解决方法都不贴就跑了?
如果您的配置没有问题,请参考33楼的解决方案。注意,问题的根源是频繁触发重试。
MrDream梦 2020-10-21
  • 打赏
  • 举报
回复
引用 54 楼 qq_36615033 的回复:
同问,麻烦楼主贴下版本
已解决 连接池大小太小
MrDream梦 2020-10-20
  • 打赏
  • 举报
回复
同问,麻烦楼主贴下版本
「已注销」 2020-10-14
  • 打赏
  • 举报
回复
我也遇到这个问题了,博主把哪个依赖升级到哪个版本解决了问题的呢
MR~零度 2020-09-24
  • 打赏
  • 举报
回复
从头看到尾,各种尝试,都无解,我之前在公司的测试开发服务器上没这种问题,是移植到生产环境linux时才出现这种问题的
doye_chen 2020-08-12
  • 打赏
  • 举报
回复
楼主,看到你说解决了,我很开心,翻了几页的帖子,就是没看到你说把redis升级到哪个版本?你是说依赖 还是脂redis服务器的版本 到底版本几?
qq_34310017 2020-07-22
  • 打赏
  • 举报
回复
问题解决了没?
  • 打赏
  • 举报
回复 2
我就服这种楼主,别人讨论回复了几个月,最后解决方法都不贴就跑了?
怪兽兔 2020-05-14
  • 打赏
  • 举报
回复
我也是这样,访问redis第一次需要20秒,后续就不用了。不知道过了多久,客户端在调用查询redis又花了20秒,这Lettuce 连接池不管用。
加载更多回复(39)

50,545

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧