ASP.NET Core 分布式 Redis 缓存:断开连接

问题描述

我在 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
 }