qq_42815818 2024-06-10 22:38 采纳率: 50%
浏览 55

关于redis客户端lettuce连接被服务器端关闭而造成连接重置导致操作失败的问题

最近在学习一个spring boot项目,其中有用到redis,正好有个腾讯云服务器闲着,练习这个项目的时候,就用云服务器使用docker部署了mysql和redis。

因为是学习项目,所以边学边操作,很多时候会比较长时间无操作,这种情况时,再操作,就会发现连接被关闭或者重置。

当报了这个异常以后,立刻再操作就可以了,因为lettuce尝试了重连,但是本次操作失败了,我也想过可以用try catch再操作一次,但是当前操作失败也要等待几秒延迟,这也是不能接受的。

查了不少资料,也问了AI,关于lettuce的心跳检测和保活配置都是假的,复制代码到IDEA中就会发现,压根没有AI中回答的配置方法。
当然,通过定时任务来操作redis保活,和换用jedis这样的方式都是查资料可查的内容。这个问题是想知道是否有不知道的配置和用法等可以解决这个问题。

异常信息中比较关键的如下:
org.springframework.data.redis.RedisSystemException: Redis exception
Caused by: io.lettuce.core.RedisException: java.net.SocketException: Connection reset
Caused by: java.net.SocketException: Connection reset

另:现在云服务器都这么狗的吗,长连接自动给断?

  • 写回答

2条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-10 22:38
    关注

    引自免费微信小程序:皆我百晓生

    面对lettuce连接Redis时遇到的连接重置问题,有几种策略可以尝试,旨在减少或消除此类中断的影响。以下是一些可能的解决方案:

    1. 配置Lettuce的KeepAlive参数

    虽然你提到的一些配置选项可能在某些版本的Lettuce中不可见,但确保keep-alive设置正确仍然是个好主意。对于Java,可以在RedisStandaloneConfigurationRedisSentinelConfiguration中调整此设置。以下是一个示例:

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    @Configuration
    public class RedisConfig {
    
        @Bean
        public RedisConnectionFactory connectionFactory() {
            LettuceConnectionFactory factory = new LettuceConnectionFactory();
            RedisStandaloneConfiguration config = (RedisStandaloneConfiguration) factory.getConfiguration();
            config.setTcpKeepAlive(true); // 启用TCP keepalive
            return factory;
        }
    
        @Bean
        public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
            RedisTemplate<String, String> template = new RedisTemplate<>();
            template.setConnectionFactory(factory);
            template.setKeySerializer(new StringRedisSerializer());
            template.setValueSerializer(new StringRedisSerializer());
            return template;
        }
    }
    

    2. 调整Redis服务器的timeout设置

    在Redis服务器端,可以通过修改redis.conf文件中的timeout值来控制空闲连接的关闭时间。默认情况下,此值为0,表示不主动关闭空闲连接。如果设为非零值(例如300秒),则Redis将定期检查并关闭超过该时长未使用的连接。这有助于防止客户端侧的意外断开,但需谨慎设置,以免影响正常操作。

    编辑redis.conf文件,找到timeout行,将其设置为你认为合适的值:

    timeout 300
    

    重启Redis服务使更改生效。

    3. 使用定时任务保持连接活跃

    尽管你提到了这一点,但在实际应用中,使用定时任务定期向Redis发送简单的PING命令可以有效防止连接因长时间闲置而被关闭。这种方法简单且易于实现,适用于大多数场景。

    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    @Component
    public class RedisConnectionKeeper {
    
        private final RedisTemplate<String, String> redisTemplate;
    
        public RedisConnectionKeeper(RedisTemplate<String, String> redisTemplate) {
            this.redisTemplate = redisTemplate;
        }
    
        @Scheduled(fixedDelay = 60000) // 每60秒执行一次
        public void keepAlive() {
            redisTemplate.execute((RedisCallback<Void>) connection -> {
                connection.ping();
                return null;
            });
        }
    }
    

    4. 检查网络配置和防火墙规则

    有时,网络设备或防火墙设置可能会导致长连接被中断。确保服务器和客户端之间的网络路径允许长时间的TCP连接,并检查防火墙规则是否不会意外地切断连接。

    结论

    通过上述方法,你可以显著降低因连接重置而导致的操作失败风险。每种方法都有其适用场景,根据实际情况选择最合适的方案进行实施。如果问题仍然存在,可能需要更深入地排查网络环境或软件配置。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月10日

悬赏问题

  • ¥15 R语言中lasso回归报错
  • ¥15 网站突然不能访问了,上午还好好的
  • ¥15 有没有dl可以帮弄”我去图书馆”秒选道具和积分
  • ¥15 semrush,SEO,内嵌网站,api
  • ¥15 Stata:为什么reghdfe后的因变量没有被发现识别啊
  • ¥15 关于#c语言#的问题,请各位专家解答!
  • ¥15 这个如何解决详细步骤
  • ¥15 在微信h5支付申请中,别人给钱就能用我的软件,这个的所属行业是啥?
  • ¥30 靶向捕获探针设计软件包
  • ¥15 别人给钱就能用我的软件,这个的经营场景是啥?