web-dev-qa-db-fra.com

Comment ConnectionMultiplexer gère-t-il les déconnexions?

La documentation Utilisation de base de StackExchange.Redis explique que la variable ConnectionMultiplexer a une longue durée de vie et qu'elle devrait être réutilisée.

Mais qu'en est-il lorsque la connexion au serveur est interrompue? Est-ce que ConnectionMultiplexer se reconnecte automatiquement, ou est-il nécessaire d'écrire le code comme dans cette réponse (en citant cette réponse):

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

Le code ci-dessus est-il une bonne solution pour gérer la récupération après déconnexion, ou aboutirait-il à plusieurs instances ConnectionMultiplexer? Dans le même ordre d'idées, comment interpréter la propriété IsConnected?

[De côté: je crois que le code ci-dessus est une très mauvaise forme d'initialisation lente, en particulier dans les environnements multithread - voir l'article de Jon Skeet sur Singletons ].

13
Gigi

Voici le modèle recommandé par l'équipe de cache Azure Redis :

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

Quelques points importants:

  • Il utilise Lazy <T> pour gérer l’initialisation thread-safe
  • Il définit "abortConnect = false", ce qui signifie que si la tentative de connexion initiale échoue, le ConnectionMultiplexer effectuera une nouvelle tentative silencieuse en arrière-plan au lieu de lancer une exception.
  • Il vérifie not la propriété IsConnected, car ConnectionMultiplexer réessayera automatiquement en arrière-plan si la connexion est interrompue.
24
Mike Harder

Oui, vous avez besoin de ce type de vérification pour résoudre les problèmes de connexion. Il faut également prendre en compte une certaine sécurité du fil. Voici comment je fais habituellement ceci:

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

Ensuite, j'utilise la propriété RedisMultiplexer partout où j'ai besoin d'appeler le noeud final Redis. Je ne stocke généralement pas le résultat de l'appel GetDatabase() car la documentation indique qu'il s'agit d'un appel assez léger.

0
CyberDude