【问题标题】:How do you handle failed redis connections你如何处理失败的 redis 连接
【发布时间】:2015-01-22 00:26:38
【问题描述】:

我将 Redis Windows 实现与 StackExchange.Redis 客户端一起使用。我的问题是,如果初始连接失败,您如何处理重新连接尝试。我正在考虑所有 Redis 主服务和从服务都关闭时的最坏情况。问题是每次我的应用程序需要缓存中的某些内容时,它都会尝试重新连接到 Redis(如果初始连接失败),这非常耗时。我的工厂类如下所示:

 private ConnectionMultiplexer GetConnection()
        {

            if (connection != null && connection.IsConnected) return connection;

            lock (_lock)
            {
                if (connection != null && connection.IsConnected) return connection;

                if (connection != null)
                {
                    logger.Log("Redis connection disconnected. Disposing connection...");
                    connection.Dispose();
                }

                logger.Log("Creating new instance of Redis Connection");


                connection = ConnectionMultiplexer.Connect(connectionString.Value);
            }

            return connection;

        }

        public IDatabase Database(int? db = null)
        {
            try
            {
                return !redisConnectionValid ? null : GetConnection().GetDatabase(db ?? settings.DefaultDb);
            }
            catch (Exception ex)
            {
                redisConnectionValid = false;
                logger.Log(Level.Error, String.Format("Unable to create Redis connection: {0}", ex.Message));
                return null;
            }
        }

您可以看到我正在使用单例模式来创建连接。如果初始连接失败,我将设置一个标志 (redisConnectionValid),以便阻止后续调用尝试重新创建连接(大约需要 5-10 秒)。还有比这更好的方法吗?我们的设计目标是即使 Redis 缓存不可用,我们的应用程序也能正常工作。我们不希望应用程序性能因为连续的 Redis 连接尝试而受到影响,这些尝试在最坏的情况下最终会失败/超时。

【问题讨论】:

    标签: redis stackexchange.redis


    【解决方案1】:

    您应该让 StackExchange.Redis 处理重新连接,而不是自己检查 IsConnected。这是我们推荐的模式:

    private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() => {
        return ConnectionMultiplexer.Connect("mycache.redis.cache.windows.net,abortConnect=false,ssl=true,password=...");
    });
    
    public static ConnectionMultiplexer Connection {
        get {
            return lazyConnection.Value;
        }
    }
    

    请注意,“abortConnect”设置为“false”。这意味着如果第一次连接尝试失败,ConnectionMultiplexer 将在后台重试,而不是抛出异常。

    【讨论】:

    • 从另一篇文章中看到“即使没有建立到Redis Cache的连接,调用也会成功”。如果没有抛出异常,那么如何确定连接失败?您会在尝试访问缓存之前查询 IsConnected 属性吗?
    • 对 Connect() 的调用不会抛出,但如果你尝试执行缓存操作(例如 StringGet())它会抛出。而且您的应用程序已经需要处理缓存操作引发的异常。
    • 所以最好不要捕获异常 -> 所以 ConnectionMultiplexer 稍后重试连接?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    • 1970-01-01
    • 2015-11-12
    • 1970-01-01
    相关资源
    最近更新 更多