Pha*_*ate 7 java spring-data-redis spring-boot spring-cache
我有一个具有以下属性的 Spring Boot 应用程序:
spring.cache.type: redis
spring.redis.host: <hostname>
spring.redis.port: <hostport>
Run Code Online (Sandbox Code Playgroud)
现在,如果远程主机发生故障,应用程序也会因连接错误而失败。在这种情况下,我的缓存不是我的应用程序的核心,但它仅用于性能,我希望 spring 简单地绕过它并转到数据库检索其数据。
我发现这可以通过定义自定义 errorHandler 方法来实现,但为了做到这一点,我必须实现 CachingConfigurer bean...但这也迫使我重写每个方法(例如缓存管理器、缓存解析器、ecc. )。
@Configuration
public class CacheConfiguration implements CachingConfigurer{
@Override
public CacheManager cacheManager() {
// TODO Auto-generated method stub
return null;
}
@Override
public CacheResolver cacheResolver() {
// TODO Auto-generated method stub
return null;
}
...
@Override
public CacheErrorHandler errorHandler() {
// the only method I need, maybe
return null;
}
Run Code Online (Sandbox Code Playgroud)
我想避免这种情况......我只需要一种方法来告诉 spring“缓存崩溃了,但没关系:假装你根本没有缓存”
@Phate - 绝对!我刚刚回答了一个相关问题(可能),使用 Apache Geode 或 Pivotal GemFire 作为具有 Spring 缓存抽象的 Spring Boot 应用程序中的缓存提供程序。
在那篇文章中,我没有完全禁用缓存,而是将 GemFire/Geode 切换为仅在本地模式下运行(GemFire/Geode 的可能配置)。但是,如果需要的话,可以应用相同的技术来完全禁用缓存。
本质上,在 Spring Boot 和 Spring 通常开始评估应用程序的配置之前,您需要一个预处理步骤。
在我的示例中,我实现了一个自定义 Spring 条件来检查集群(即服务器)的可用性。然后我将其应用Condition到我的@Configuration课堂上。
对于 Spring Boot,当 Spring Boot在应用程序的类路径上有效地看到(以及参见此处)Redis 和 Spring Data Redis 时,它会为 Redis 应用自动配置(作为存储和缓存提供程序) 。因此,本质上,Redis 仅在“条件”为true时才启用为缓存提供程序,主要是
由您的应用程序配置声明了一个bean ,这是您的责任。RedisConnectionFactory
那么,这会是什么样子呢?
就像我的 Apache Geode 和 Pivotal GemFire自定义 Spring Condition一样,您可以为 Redis 实现类似的 Condition,例如:
static RedisAvailableCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext,
AnnotatedTypeMetadata annotatedTypeMetadata) {
// Check the available of the Redis server, such as by opening a Socket
// connection to the server node.
// NOTE: There might be other, more reliable/robust means of checking
// the availability of a Redis server in the Redis community.
Socket redisServer;
try {
Environment environment = conditionContext.getEnvironment();
String host = environment.getProperty("spring.redis.host");
Integer port = environment.getProperty("spring.redis.port", Integer.class);
SocketAddress redisServerAddress = new InetSocketAddress(host, port);
redisServer = new Socket();
redisServer.connect(redisServerAddress);
return true;
}
catch (Throwable ignore) {
System.setProperty("spring.cache.type", "none");
return false;
}
finally {
// TODO: You need to implement this method yourself.
safeCloseSocket(redisServer);
}
}
}
Run Code Online (Sandbox Code Playgroud)
此外,我还设置spring.cache.type为NONE,以确保在 Redis 不可用的情况下将缓存呈现为无操作。 这里NONE有更详细的解释。
当然,您也可以使用后备缓存选项,使用其他缓存提供程序(例如简单的ConcurrentHashMap,但我将其作为练习留给您)。向前...
然后,在定义了RedisConnectionFactorybean 的 Spring Boot 应用程序配置类中(按照 Spring Boot 自动配置的预期),Condition使用 Spring 的@Conditiional注释添加此自定义,如下所示:
@Confgiuration
@Conditional(RedisAvailableCondition.class);
class MyRedisConfiguration {
@Bean
RedisConnectionFactory redisConnectionFactory() {
// Construct and return new RedisConnectionFactory
}
}
Run Code Online (Sandbox Code Playgroud)
这应该可以有效地处理 Redis 不可用的情况。
免责声明:我自己没有对此进行测试,但基于我的 Apache Geode/Pivotal GemFire 示例,该示例确实有效。因此,也许通过一些调整,这将满足您的需求。它还应该可以为您提供一些想法。
希望这可以帮助!
干杯!
| 归档时间: |
|
| 查看次数: |
4201 次 |
| 最近记录: |