ConnectionMultiplexer如何处理断开连接?

时间:2015-03-01 09:57:00

标签: c# redis stackexchange.redis

StackExchange.Redis的Basic Usage文档解释说ConnectionMultiplexer是长期存在的,预计会被重用。

但是当与服务器的连接断开时呢? ConnectionMultiplexer会自动重新连接,还是必须像this answer中那样编写代码(引用该答案):

        if (RedisConnection == null || !RedisConnection.IsConnected)
        {
            RedisConnection = ConnectionMultiplexer.Connect(...);
        }
        RedisCacheDb = RedisConnection.GetDatabase();

上述代码是否适合处理断开连接的恢复,或者它实际上会导致多个ConnectionMultiplexer实例?同样,如何解释IsConnected属性?

[旁白:我相信上面的代码是一种非常糟糕的延迟初始化形式,特别是在多线程环境中 - 请参阅Jon Skeet's article on Singletons]。

2 个答案:

答案 0 :(得分:25)

以下是pattern recommended by the Azure Redis Cache team

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

一些要点:

  • 它使用Lazy&lt; T&gt;。处理线程安全初始化
  • 设置&#34; abortConnect = false&#34;,这意味着如果初始连接尝试失败,ConnectionMultiplexer将在后台静默重试,而不是抛出异常。
  • 检查IsConnected属性,因为如果连接断开,ConnectionMultiplexer将在后台自动重试。

答案 1 :(得分:0)

是的,您需要这种类型的验证才能修复断开的连接。还应该考虑一些线程安全性。这就是我通常这样做的方式:

private static ConnectionMultiplexer _redis;
private static readonly Object _multiplexerLock = new Object();

private void ConnectRedis()
{
    try
    {
        _redis = ConnectionMultiplexer.Connect("...<connection string here>...");
    }
    catch (Exception ex)
    {
        //exception handling goes here
    }
}


private ConnectionMultiplexer RedisMultiplexer
{
    get
    {
        lock (_multiplexerLock)
        {
            if (_redis == null || !_redis.IsConnected)
            {
                ConnectRedis();
            }
            return _redis;
        }
    }
}

然后我在需要调用Redis端点的地方使用RedisMultiplexer属性。我通常不会存储GetDatabase()电话的结果,因为文档说这是一个非常轻量级的电话。