You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Data Redis自定义错误处理:宕机后接口超时、重连日志问题咨询

Spring Data Redis 透明缓存降级:解决运行时宕机阻塞与冗余重连日志

根因说明

  • 现有自定义CacheErrorHandler仅能在缓存操作抛出异常后做兜底,无法干预Lettuce(Spring Boot默认Redis客户端)的连接、命令执行逻辑。默认配置下Lettuce命令超时、连接获取超时长达分钟级,且连接断开时默认会缓存待执行命令等待重连,直接导致请求阻塞。
  • ConnectionWatchdog是Lettuce内置的自动重连组件,默认无限重试重连,并按INFO/WARN级别打印重连日志,产生冗余日志输出。

落地步骤

1. 调整Lettuce客户端配置,实现缓存操作快速失败

核心是让Redis连接异常时命令立刻抛出异常,不要排队等待重连,从根源消除阻塞。
首先在application.yml中添加基础超时配置:

spring:
  redis:
    timeout: 200ms # Redis命令执行超时阈值
    lettuce:
      pool:
        max-wait: 100ms # 从连接池获取连接的最大等待时间
        max-active: 8
        max-idle: 8
        min-idle: 2
      shutdown-timeout: 100ms

再添加自定义Lettuce客户端配置,修改断开连接时的命令处理策略:

@Configuration
public class LettuceCustomConfig {
    @Bean
    public LettuceClientConfigurationBuilderCustomizer lettuceCustomizer() {
        return builder -> builder.clientOptions(ClientOptions.builder()
                        // 连接断开时直接拒绝执行命令,不排队等待重连,实现快速失败
                        .disconnectedBehavior(ClientOptions.DisconnectedBehavior.REJECT_COMMANDS)
                        .connectTimeout(Duration.ofMillis(100))
                        // 保留自动重连能力,Redis恢复后无需重启即可自动恢复缓存
                        .autoReconnect(true)
                        .build())
                .commandTimeout(Duration.ofMillis(200));
    }
}

2. 修复现有自定义缓存错误处理器的拼写问题

原代码中@Slf4n为注解拼写错误,修正为@Slf4j,优化日志打印内容方便排查:

@Slf4j
public class CustomCacheErrorHandler implements CacheErrorHandler {
    @Override
    public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) {
        log.error("Cache get failed, cacheName:{}, key:{}, err:{}", cache.getName(), key, exception.getMessage());
    }

    @Override
    public void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value) {
        log.error("Cache put failed, cacheName:{}, key:{}, err:{}", cache.getName(), key, exception.getMessage());
    }

    @Override
    public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) {
        log.error("Cache evict failed, cacheName:{}, key:{}, err:{}", cache.getName(), key, exception.getMessage());
    }

    @Override
    public void handleCacheClearError(RuntimeException exception, Cache cache) {
        log.error("Cache clear failed, cacheName:{}, err:{}", cache.getName(), exception.getMessage());
    }
}

3. 屏蔽ConnectionWatchdog冗余重连日志

在application.yml中调整该类的日志输出级别,仅打印ERROR级别的日志:

logging:
  level:
    io.lettuce.core.protocol.ConnectionWatchdog: ERROR

效果验证

配置完成后可达到预期效果:

  • Redis正常运行时,缓存能力不受任何影响
  • Redis运行中宕机时,缓存操作会在百毫秒级快速失败,被自定义错误处理器捕获后仅打印错误日志,API直接执行业务主逻辑(如直接查询数据库),无分钟级阻塞问题
  • 不再打印INFO/WARN级别的自动重连日志
  • Redis恢复后,Lettuce会自动重建连接,缓存能力自动恢复,无需重启应用

内容的提问来源于stack exchange,提问作者tweetysat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 00:39:18