it-swarm.com.de

Wie geht der ConnectionMultiplexer mit Verbindungsabbrüchen um?

In der Basic Usage - Dokumentation für StackExchange.Redis wird erklärt, dass das ConnectionMultiplexer-Objekt eine lange Lebensdauer hat und voraussichtlich wiederverwendet wird.

Aber was ist, wenn die Verbindung zum Server unterbrochen wird? Stellt ConnectionMultiplexer die Verbindung automatisch wieder her oder muss Code wie in diese Antwort (unter Angabe dieser Antwort) geschrieben werden:

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

Ist der obige Code für die Wiederherstellung nach Verbindungsabbrüchen geeignet, oder würde er tatsächlich zu mehreren ConnectionMultiplexer -Instanzen führen? Wie sollte in diesem Sinne die Eigenschaft IsConnected interpretiert werden?

[Abgesehen davon: Ich glaube, der obige Code ist eine ziemlich schlechte Form der verzögerten Initialisierung, insbesondere in Multithread-Umgebungen - siehe Jon Skeets Artikel über Singletons ].

13
Gigi

Hier ist das Muster, das vom Azure Redis Cache-Team empfohlen wird :

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

Einige wichtige Punkte:

  • Es verwendet Lazy <T>, um die Thread-sichere Initialisierung durchzuführen
  • Es setzt "abortConnect = false", dh wenn der erste Verbindungsversuch fehlschlägt, versucht ConnectionMultiplexer im Hintergrund, anstatt eine Ausnahme auszulösen.
  • Es prüft nicht die IsConnected-Eigenschaft, da ConnectionMultiplexer automatisch im Hintergrund einen Neustart durchführt, wenn die Verbindung getrennt wird.
24
Mike Harder

Ja, Sie benötigen diese Art der Überprüfung, um unterbrochene Verbindungen zu reparieren. Etwas Gewindesicherheit sollte ebenfalls berücksichtigt werden. So mache ich das normalerweise:

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

Dann verwende ich die RedisMultiplexer-Eigenschaft überall, wo ich den Redis-Endpunkt aufrufen muss. Normalerweise speichere ich das Ergebnis des GetDatabase()-Aufrufs nicht, da die Dokumentation besagt, dass es sich um einen recht einfachen Aufruf handelt.

0
CyberDude