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
相关产品推荐
相关产品推荐

