我使用Redis缓存作为ASP中的分布式缓存。NET应用程序。它一直工作到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提供程序的插件。
看看吧。
首先,为什么Redis服务器不可用?持续多久?你应该尽量减少这种情况。您是否使用Redis作为AWS的服务,即ElasticCache?如果是这样,您可以将其配置为在第一个主服务器出现故障时将新的Redis slave/read replice服务器升级为主服务器。
要提高容错能力并减少写入停机时间,请为Redis启用带自动故障切换的Multi-AZ(群集模式已禁用(具有副本的群集。有关详细信息,请参见最小化使用Multi AZ的Redis的ElastiCache停机时间。
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
}