【问题标题】:Spring Cache with Redis - How to gracefully handle or even skip Caching in case of Connection Failure to RedisSpring Cache with Redis - 如果与 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

【问题讨论】:

    标签: spring-cache spring-data-redis


    【解决方案1】:

    您可以按照 Stephane Nicoll 的建议使用 CacheErrorHandler。但你应该确保 RedisCacheManager transactionAwarefalse 在你的 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
      猜你喜欢
      • 2012-06-01
      • 2015-05-14
      • 2015-01-22
      • 2020-01-07
      • 2021-04-27
      • 2022-08-03
      • 2020-04-20
      • 2015-09-25
      • 1970-01-01
      相关资源
      最近更新 更多