gpt4 book ai didi

spring-boot - 使用 spring boot 多次超时时禁用 redis

转载 作者:行者123 更新时间:2023-12-04 17:38:10 31 4
gpt4 key购买 nike

我在 AWS EC2 中部署了一个应用程序,有一段时间(很少),我无法在 redis 中连接和执行任何命令,我正在调查此问题的根本原因。

我正在使用 Spring Boot + Redis (Elasticcache)。

我正在使用包装器来捕获任何异常以继续请求过程。

我的包装:

class RedisCacheWrapper implements Cache {

private final Cache delegate;

public RedisCacheWrapper(Cache redisCache) {
Assert.notNull(redisCache, "delegate cache must not be null");
this.delegate = redisCache;
}

@Override
public String getName() {
try {
return delegate.getName();
} catch (Exception e) {
return handleException(e);
}
}

@Override
public Object getNativeCache() {
try {
return delegate.getNativeCache();
} catch (Exception e) {
return handleException(e);
}
}

@Override
public ValueWrapper get(Object key) {
try {
return delegate.get(key);
} catch (Exception e) {
return handleException(e);
}
}

@Override
public <T> T get(Object o, Class<T> type) {
try {
return delegate.get(o, type);
} catch (Exception e) {
return handleException(e);
}
}

@Override
public <T> T get(Object o, Callable<T> callable) {
try {
return delegate.get(o, callable);
} catch (Exception e) {
return handleException(e);
}
}

@Override
public void put(Object key, Object value) {
try {
delegate.put(key, value);
} catch (Exception e) {
handleException(e);
}
}

@Override
public ValueWrapper putIfAbsent(Object o, Object o1) {
try {
return delegate.putIfAbsent(o, o1);
} catch (Exception e) {
return handleException(e);
}
}

@Override
public void evict(Object o) {
try {
delegate.evict(o);
} catch (Exception e) {
handleException(e);
}
}

@Override
public void clear() {
try {
delegate.clear();
} catch (Exception e) {
handleException(e);
}
}

private <T> T handleException(Exception e) {
log.error("handleException", e);
return null;
}}

在我的 redis 配置中,我将超时设置为 1 秒。因此,当连接/命令在 1 秒后未执行时,redis 会抛出如下异常:
Caused by: io.lettuce.core.RedisCommandTimeoutException: Command timed out

我的疑问:
有一个临时禁用缓存的好方法(没有任何部署),而redis不好?例如:使用断路器?

我认为这样做:
    @Cacheable()
myMethodCached(){
myRealMethod();
}

myRealMethod(){}

将myMethodCached放入HystrixCommand中,如果抛出超时,则不使用redis执行fallback方法。

这种方法的问题是我需要为所有使用缓存的方法创建一个“回退”,我想全局“禁用”(所有缓存将被跳过)。

在一段时间内“禁用”redis 有没有好的解决方案?

最佳答案

如果您使用的是 Spring Data Redis,则可以利用 Spring 的支持通过自定义异常处理程序处理这些临时中断和异常。
代码:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
建议将超时时间设置为低于默认值(60000):
spring.cache.type=redis
spring.redis.timeout=100
然后在 Spring 上下文中创建一个自定义错误处理程序:
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.Cache;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.context.annotation.Configuration;

@Slf4j
@EnableCaching
@Configuration
public class CacheConfiguration extends CachingConfigurerSupport {

@Override
public CacheErrorHandler errorHandler() {
return new CacheErrorHandler() {
@Override
public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) {
log.info("Failure getting from cache: " + cache.getName() + ", exception: " + exception.toString());
}

@Override
public void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value) {
log.info("Failure putting into cache: " + cache.getName() + ", exception: " + exception.toString());
}

@Override
public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) {
log.info("Failure evicting from cache: " + cache.getName() + ", exception: " + exception.toString());
}

@Override
public void handleCacheClearError(RuntimeException exception, Cache cache) {
log.info("Failure clearing cache: " + cache.getName() + ", exception: " + exception.toString());
}
};
}

}
Spring 应该在 100 毫秒后检测到故障并回退以检索通过 @Cacheable 检索到的数据。注释方法通常就好像存在缓存未命中一样。每当缓存恢复时,Spring 将再次开始从缓存中提取。

关于spring-boot - 使用 spring boot 多次超时时禁用 redis,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55712815/

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