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

发布于 01-09 06:47 字数 7421 浏览 5 评论 0原文

我有asp.net core 3.1应用程序利用Azure Redis缓存和nuget包:StackExchange.Redis(版本: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();
    }
}

Startup.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

I have asp.net core 3.1 application leveraging Azure Redis Cache with nuget package : StackExchange.Redis (Version: 2.2.62). Here I am trying to reset the Cache at every app startup event with the following code:

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();
    }
}

Startup.cs

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

On executing the code I see the below error:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜警司2025-01-16 06:47:18

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

  • StackExchange.Redis 降级到 2.1.58

  • 不要分别使用端点和密码创建 ConfigurationOptions 参数,而是使用“主连接”来自 Azure 访问密钥的字符串 (StackExchange.Redis)" 作为 ConnectionMultiplexer.Connect()

    的参数

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

请参阅此处了解更多信息。

Please check if the below given steps help to work around:

  • downgrading StackExchange.Redis to 2.1.58

  • Instead of creating a ConfigurationOptions parameter using the Endpoint and Password separately, use the "Primary connection string (StackExchange.Redis)" from Azure Access Keys as the parameter to ConnectionMultiplexer.Connect()

  • Set the ssl=True,sslprotocols=tls12 in your configuration to force it to the latest version if you're utilizing a secure TLS connection.

Refer here for more information.

善良天后2025-01-16 06:47:18

就我而言,我在 Azure Portal>YourRedisCache>Settings>FireWall 下为 Redis 客户端计算机定义并忘记了防火墙规则。这导致 Redis 拒绝任何其他连接。当我删除该防火墙规则时,它工作正常。

In my case, I had defined and forgot a firewall rule for my client machine for Redis under Azure Portal>YourRedisCache>Settings>FireWall. This caused Redis to reject any other connections. When I deleted that firewall rule, it worked fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文