问题描述
我在 ASP.NET 应用程序中使用 Redis 缓存作为分布式缓存。 它一直工作到 Redis 服务器变得不可用,问题是: 如何妥善处理掉线问题?
Redis 是这样配置的(Startup.cs):
services.AdddistributedRedisCache(...)
选项 AbortOnConnectFail 设置为 false
通过构造函数注入服务:
...
private IdistributedCache _cache
public MyService(IdistributedCache cache)
{
_cache = cache;
}
当 Redis 关闭时,以下代码抛出异常 (StackExchange.Redis.RedisConnectionException: SocketFailure on 127.0.0.1:6379/Subscription ...):
var val = await _cache.GetAsync(key,cancellationToken);
我不认为使用反射来检查 _cache 对象内部的连接状态是一个好方法。那么是否有任何“正确”的选择来处理它?
解决方法
也许您可以检查 Polly Project。它具有 Retry/WaitAndRetry/RetryForever 和可以方便的断路器。所以你可以抓住那个 RedisConnectionException
然后重试或回退到其他方法。
您有 Microsoft DistributedCache Provider 插件。
检查一下。
,首先,为什么您的 Redis 服务器变得不可用?以及多久?您应该尽量减少此类情况。您是否使用 Redis 作为 AWS 的服务,即 ElasticCache?如果是这样,您可以将其配置为在第一个 master 失败时将新的 Redis slave /read-replice 服务器提升为 master。
为了提高容错能力并减少写入停机时间,请为您的 Redis(集群模式)启用具有自动故障转移功能的多可用区 已禁用)具有副本的集群。有关更多信息,请参阅最小化 具有多可用区的 ElastiCache for Redis 停机时间。
https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/AutoFailover.html
除此之外,Redis 服务器无响应的后备解决方案只是在 Redis 服务器关闭时从数据库中检索您在 Redis 中缓存的对象/实体。您可以重试两次 Redis 调用,每次重试之间间隔 5 秒,如果服务器仍然关闭,您应该只查询数据库。这会导致性能下降,但这是比抛出错误更好的解决方案。
T val = null;
int retryCount = 0;
do
{
try
{
val = await _cache.GetAsync(key,cancellationToken);
}
catch(Exception ex)
{
retryCount++;
Thread.Sleep(retryCount * 2000)
}
}
while(retryCount < 3 && val == null);
if (val == null)
{
var = call to database
}