Spring Cache with Redis - 如果与 Redis 的连接失败,如何优雅地处理甚至跳过缓存
Posted
技术标签:
【中文标题】Spring Cache with Redis - 如果与 Redis 的连接失败,如何优雅地处理甚至跳过缓存【英文标题】:Spring Cache with Redis - How to gracefully handle or even skip Caching in case of Connection Failure to Redis 【发布时间】:2015-02-26 18:14:39 【问题描述】:我已在我的 Spring 应用程序中启用缓存,并使用 Redis 来实现此目的。 但是,每当发生连接故障时,应用程序就会停止工作,而我认为它最好 跳过缓存并继续正常的执行流程。
那么,有没有人知道如何在 Spring 中优雅地做到这一点?
这是我得到的例外。
Caused by: org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
【问题讨论】:
【参考方案1】:您可以按照 Stephane Nicoll 的建议使用 CacheErrorHandler
。但你应该确保
RedisCacheManager transactionAware
到 false
在你的 Redis 缓存配置中(以确保在执行缓存部分时尽早提交事务并且错误被 CacheErrorHandler
捕获,不要等到跳过 @987654325 的执行结束@ 部分)。将transactionAware
设置为false
的函数如下所示:
@Bean
public RedisCacheManager redisCacheManager(LettuceConnectionFactory lettuceConnectionFactory)
JdkSerializationRedisSerializer redisSerializer = new JdkSerializationRedisSerializer(getClass().getClassLoader());
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(redisDataTTL))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer));
redisCacheConfiguration.usePrefix();
RedisCacheManager redisCacheManager = RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(lettuceConnectionFactory)
.cacheDefaults(redisCacheConfiguration)
.build();
redisCacheManager.setTransactionAware(false);
return redisCacheManager;
【讨论】:
它对我有用,但我害怕将缓存排除在事务之外【参考方案2】:Stephane Nicoll 建议的 CacheErrorHandler 很有用。但是当它无法创建与redis的连接时,它并没有帮助。
像@Cacheable Stills 这样的缓存方法失败并出现 RedisConnectionFailureException。
【讨论】:
对我来说也一样。你找到解决办法了吗?【参考方案3】:与 Stephane 提到的类似,我通过使用 try catch 块中的错误来完成。添加一个回退机制,如果 Redis 未启动或数据不存在,则我从 DB 中获取数据。(稍后如果我找到一个,然后我在 Redis 中添加相同的数据,如果它是为了保持一致性。 )
【讨论】:
【参考方案4】:从 Spring Framework 4.1 开始,您可以实现一个 CacheErrorHandler
来处理此类异常。详情请参考to the javadoc。
您可以通过让您的@Configuration
类扩展CachingConfigurerSupport
来注册它(请参阅errorHandler()
)。
【讨论】:
非常感谢您的建议。我的@Configuration
类已经扩展了 SpringBootServletInitializer,因此,我尝试直接从我的@Configuration
类中实现 CacheErrorHandler。但是,它似乎无法处理 RedisConnectionFailureException 之类的任何问题。
您在哪里看到了对SpringBootServletInitializer
的引用?我写了CachingConfigurerSupport
- 为此,您需要 Spring Boot 1.2 (Spring 4.1)。
CacheErrorHandler 仅在缓存操作期间使用。 Redis 连接失败可能发生在更高层?
呃?上级是什么意思?
我想他大概的意思是当连接失败时,可能不会触发CacheErrorHandler以上是关于Spring Cache with Redis - 如果与 Redis 的连接失败,如何优雅地处理甚至跳过缓存的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot 整合 Spring Cache + Redis
spring-boot Cache redis 类型转换错误
Spring Boot之集成Redis:Spring Cache + Redis
Spring Boot集成Spring Cache 和 Redis