没有任何连接处于活动状态/可用于服务此操作:FLUSHALL;无法连接到redis服务器



我有一个asp.net核心3.1应用程序,它利用了带有nuget包的Azure Redis缓存:StackExchange.RRedis(版本:2.2.62(。在这里,我试图在每次应用程序启动事件时重置缓存,代码如下:

ResetCacheService.cs

public class ResetCacheService : IHostedService
{
private readonly IServiceProvider _serviceProvider;
public ResetCacheService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
// Create a new scope to retrieve scoped services
using (var scope = _serviceProvider.CreateScope())
{
// Get the CacheProvider instance
var redisCache = scope.ServiceProvider.GetRequiredService<ICacheProvider>();
//Do the cache reset asynchronously
await redisCache.ClearCacheAsync();
}
}
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}

ICacheProvider.cs

public interface ICacheProvider
{
IList<string> GetKeys();
IList<string> GetKeys(string strGroup);
T Get<T>(string strKey, string strGroup = "");
bool Set(string strKey, object objData, string strGroup = "", int? intMinutes = null);
bool Remove(string strKey, string strGroup = "");
bool RemoveGroup(string strGroup);
bool ClearCache();
Task ClearCacheAsync();
}

CacheProvider.cs

public class CacheProvider : ICacheProvider
{
private static readonly int ExpiryMinutes = ConfigManager.Get(C.AppKeys.CacheExpiryMinutes, C.Defaults.CacheExpiryMinutes);
private static Lazy<ConnectionMultiplexer> _objCacheConn = CreateConnection();
private static Lazy<ConnectionMultiplexer> CreateConnection()
{
return new Lazy<ConnectionMultiplexer>(() =>
{
string strConn = ConfigManager.Get(C.VaultKeys.RedisConnString);
return ConnectionMultiplexer.Connect(strConn);
});
}
private ConnectionMultiplexer Connection
{
get
{
return _objCacheConn.Value;
}
}
private IDatabase GetDatabase()
{
return Connection.GetDatabase();
}
private EndPoint[] GetEndPoints()
{
return Connection.GetEndPoints();
}
private IServer GetServer()
{
var objEndpoint = GetEndPoints().First();
return Connection.GetServer(objEndpoint);
}
public IList<string> GetKeys()
{
return GetKeys("*");
}
public IList<string> GetKeys(string strGroup)
{
var lstKeys = new List<string>();
try
{
var objServer = GetServer();
if (objServer != null)
{
var strPattern = strGroup + ":*";
var objRedisKeys = objServer.Keys(pattern: strPattern);
var objLst = objRedisKeys.GetEnumerator();
while (objLst.MoveNext())
{
lstKeys.Add(objLst.Current.ToString());
}
}
}
catch (Exception)
{
lstKeys = new List<string>();
}
return lstKeys;
}
public T Get<T>(string strKey, string strGroup = "")
{
T objData = default(T);
try
{
var objCache = GetDatabase();
if (!strKey.IsEmpty() && objCache != null)
{
strKey = (strGroup.IsEmpty() ? C.CacheGroups.General : strGroup) + ":" + strKey;
var strData = objCache.StringGet(strKey).ToString();
if (!strData.IsEmpty())
{
objData = JsonConvert.DeserializeObject<T>(strData);
}
}
}
catch (Exception)
{
objData = default(T);
}
return objData;
}
public bool Set(string strKey, object objData, string strGroup = "", int? intMinutes = null)
{
bool blnSuccess = false;
try
{
var objCache = GetDatabase();
if (!strKey.IsEmpty() && objData != null && objCache != null)
{
intMinutes = intMinutes ?? ExpiryMinutes;
strKey = (strGroup.IsEmpty() ? C.CacheGroups.General : strGroup) + ":" + strKey;
var strData = JsonConvert.SerializeObject(objData);
var tsExpiry = new TimeSpan(0, intMinutes.Value, 0);
blnSuccess = objCache.StringSet(strKey, strData, tsExpiry);
}
}
catch (Exception)
{
blnSuccess = false;
}
return blnSuccess;
}
public bool Remove(string strKey, string strGroup = "")
{
bool blnSuccess = false;
try
{
var objCache = GetDatabase();
if (!strKey.IsEmpty() && objCache != null)
{
strKey = (strGroup.IsEmpty() ? C.CacheGroups.General : strGroup) + ":" + strKey;
blnSuccess = objCache.KeyDelete(strKey);
}
}
catch (Exception)
{
blnSuccess = false;
}
return blnSuccess;
}
public bool RemoveGroup(string strGroup)
{
bool blnSuccess = false;
try
{
var lstKeys = GetKeys(strGroup);
var objCache = GetDatabase();
if (lstKeys.Count > 0 && objCache != null)
{
foreach (var strKey in lstKeys)
{
objCache.KeyDelete(strKey);
}
blnSuccess = true;
}
}
catch (Exception)
{
blnSuccess = false;
}
return blnSuccess;
}
public bool ClearCache()
{
bool blnSuccess = false;
try
{
var objServer = GetServer();
if (objServer != null)
{
objServer.FlushAllDatabases();
blnSuccess = true;
}
}
catch (Exception)
{
blnSuccess = false;
}
return blnSuccess;
}
/// <summary>
/// Reset the Cache
/// </summary>
/// <returns></returns>
public async Task ClearCacheAsync()
{
var server = GetServer();
await server.FlushAllDatabasesAsync();
}
}

启动.cs

public static IServiceCollection AddCacheResetHostedService(this IServiceCollection services) => services.AddHostedService<ResetCacheService>();
public virtual void ConfigureServices(IServiceCollection services) => services.AddConfigManager(this.configuration).AddCacheResetHostedService();

在执行代码时,我看到以下错误:

No connection is active/available to service this operation: FLUSHALL; It was not possible to connect to the redis server(s). ConnectTimeout, inst: 0, qu: 0, qs: 0, aw: False, rs: NotStarted, ws: Initializing, in: 0, serverEndpoint: daqmmredis.redis.cache.windows.net:6380, mc: 1/1/0, mgr: 10 of 10 available, clientName: USHYDSAPATRO7, IOCP: (Busy=0,Free=1000,Min=8,Max=1000), WORKER: (Busy=0,Free=32767,Min=8,Max=32767), v: 2.2.62.27853

请检查以下给定步骤是否有助于解决问题:

  • StackExchange.Redis降级为2.1.58

  • 代替单独使用Endpoint和Password来创建ConfigurationOptions参数;主连接串(StackExchange.Redis(";从Azure访问密钥作为ConnectionMultiplexer.Connect()的参数

  • 如果您使用安全TLS连接,请在配置中设置ssl=True,sslprotocols=tls12以强制其为最新版本。

有关详细信息,请参阅此处。

在我的案例中,我为Azure Portal下的Redis客户端机器定义并忘记了防火墙规则>YourReadsCache>设置>防火墙。这导致Redis拒绝任何其他连接。当我删除防火墙规则时,它运行良好。

最新更新