gpt4 book ai didi

Spring @Cacheable redis异常不影响正常业务方案

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 31 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章Spring @Cacheable redis异常不影响正常业务方案由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

背景

项目中,使用@Cacheable进行数据缓存。发现:当redis宕机之后,@Cacheable注解的方法并未进行缓存冲突,而是直接抛出异常。而这样的异常会导致服务不可用.

原因分析

我们是通过@EnableCaching进行缓存启用的,因此可以先看@EnableCaching的相关注释 。

Spring @Cacheable redis异常不影响正常业务方案

通过@EnableCaching的类注释可发现,spring cache的核心配置接口为:org.springframework.cache.annotation.CachingConfigurer 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/**
  * Interface to be implemented by @{@link org.springframework.context.annotation.Configuration
  * Configuration} classes annotated with @{@link EnableCaching} that wish or need to
  * specify explicitly how caches are resolved and how keys are generated for annotation-driven
  * cache management. Consider extending {@link CachingConfigurerSupport}, which provides a
  * stub implementation of all interface methods.
  *
  * <p>See @{@link EnableCaching} for general examples and context; see
  * {@link #cacheManager()}, {@link #cacheResolver()} and {@link #keyGenerator()}
  * for detailed instructions.
  *
  * @author Chris Beams
  * @author Stephane Nicoll
  * @since 3.1
  * @see EnableCaching
  * @see CachingConfigurerSupport
  */
public interface CachingConfigurer {
 
  /**
  * Return the cache manager bean to use for annotation-driven cache
  * management. A default {@link CacheResolver} will be initialized
  * behind the scenes with this cache manager. For more fine-grained
  * management of the cache resolution, consider setting the
  * {@link CacheResolver} directly.
  * <p>Implementations must explicitly declare
  * {@link org.springframework.context.annotation.Bean @Bean}, e.g.
  * <pre class="code">
  * Configuration
  * EnableCaching
  * public class AppConfig extends CachingConfigurerSupport {
  *  Bean // important!
  *  Override
  *  public CacheManager cacheManager() {
  *   // configure and return CacheManager instance
  *  }
  *  // ...
  * }
  * </pre>
  * See @{@link EnableCaching} for more complete examples.
  */
  CacheManager cacheManager();
 
  /**
  * Return the {@link CacheResolver} bean to use to resolve regular caches for
  * annotation-driven cache management. This is an alternative and more powerful
  * option of specifying the {@link CacheManager} to use.
  * <p>If both a {@link #cacheManager()} and {@code #cacheResolver()} are set,
  * the cache manager is ignored.
  * <p>Implementations must explicitly declare
  * {@link org.springframework.context.annotation.Bean @Bean}, e.g.
  * <pre class="code">
  * Configuration
  * EnableCaching
  * public class AppConfig extends CachingConfigurerSupport {
  *  Bean // important!
  *  Override
  *  public CacheResolver cacheResolver() {
  *   // configure and return CacheResolver instance
  *  }
  *  // ...
  * }
  * </pre>
  * See {@link EnableCaching} for more complete examples.
  */
  CacheResolver cacheResolver();
 
  /**
  * Return the key generator bean to use for annotation-driven cache management.
  * Implementations must explicitly declare
  * {@link org.springframework.context.annotation.Bean @Bean}, e.g.
  * <pre class="code">
  * Configuration
  * EnableCaching
  * public class AppConfig extends CachingConfigurerSupport {
  *  Bean // important!
  *  Override
  *  public KeyGenerator keyGenerator() {
  *   // configure and return KeyGenerator instance
  *  }
  *  // ...
  * }
  * </pre>
  * See @{@link EnableCaching} for more complete examples.
  */
  KeyGenerator keyGenerator();
 
  /**
  * Return the {@link CacheErrorHandler} to use to handle cache-related errors.
  * <p>By default,{@link org.springframework.cache.interceptor.SimpleCacheErrorHandler}
  * is used and simply throws the exception back at the client.
  * <p>Implementations must explicitly declare
  * {@link org.springframework.context.annotation.Bean @Bean}, e.g.
  * <pre class="code">
  * Configuration
  * EnableCaching
  * public class AppConfig extends CachingConfigurerSupport {
  *  Bean // important!
  *  Override
  *  public CacheErrorHandler errorHandler() {
  *   // configure and return CacheErrorHandler instance
  *  }
  *  // ...
  * }
  * </pre>
  * See @{@link EnableCaching} for more complete examples.
  */
  CacheErrorHandler errorHandler();
 
}

该接口errorHandler方法可配置异常的处理方式。通过该方法上的注释可以发现,默认的CacheErrorHandler实现类是org.springframework.cache.interceptor.SimpleCacheErrorHandler 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
  * A simple {@link CacheErrorHandler} that does not handle the
  * exception at all, simply throwing it back at the client.
  *
  * @author Stephane Nicoll
  * @since 4.1
  */
public class SimpleCacheErrorHandler implements CacheErrorHandler {
 
  @Override
  public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) {
  throw exception;
  }
 
  @Override
  public void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value) {
  throw exception;
  }
 
  @Override
  public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) {
  throw exception;
  }
 
  @Override
  public void handleCacheClearError(RuntimeException exception, Cache cache) {
  throw exception;
  }
}

SimpleCacheErrorHandler类注释上说明的很清楚:对cache的异常不做任何处理,直接将该异常抛给客户端。因此默认的情况下,redis服务器异常后,直接就阻断了正常业务 。

解决方案

通过上面的分析可知,我们可以通过自定义CacheErrorHandler来干预@Cacheable的异常处理逻辑。具体代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class RedisConfig extends CachingConfigurerSupport {
 
   /**
    * redis数据操作异常处理。该方法处理逻辑:在日志中打印出错误信息,但是放行。
    * 保证redis服务器出现连接等问题的时候不影响程序的正常运行
    */
   @Override
   public CacheErrorHandler errorHandler() {
     return new CacheErrorHandler() {
       @Override
       public void handleCachePutError(RuntimeException exception, Cache cache,
                       Object key, Object value) {
         handleRedisErrorException(exception, key);
       }
 
       @Override
       public void handleCacheGetError(RuntimeException exception, Cache cache,
                       Object key) {
         handleRedisErrorException(exception, key);
       }
 
       @Override
       public void handleCacheEvictError(RuntimeException exception, Cache cache,
                        Object key) {
         handleRedisErrorException(exception, key);
       }
 
       @Override
       public void handleCacheClearError(RuntimeException exception, Cache cache) {
         handleRedisErrorException(exception, null );
       }
     };
   }
 
   protected void handleRedisErrorException(RuntimeException exception, Object key) {
     log.error( "redis异常:key=[{}]" , key, exception);
   }
}

到此这篇关于Spring @Cacheable redis异常不影响正常业务方案的文章就介绍到这了,更多相关Spring @Cacheable redis异常内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。

原文链接:https://juejin.cn/post/6930545205036875784 。

最后此篇关于Spring @Cacheable redis异常不影响正常业务方案的文章就讲到这里了,如果你想了解更多关于Spring @Cacheable redis异常不影响正常业务方案的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com