2017-01-16 10 views
3

В принципе, у меня есть сценарий "DON'T DO THIS" Sentinel. Потому что Страж не является безопасным в таком случае, я реализовал следующиеStackExchange.Redis - Как изменить конфигурацию во время выполнения?

var main = "192.168.XXX.YY:6379,abortConnect=false"; 
var backup = "192.168.XXX.YY:6379,abortConnect=false"; 

IConnectionMultiplexer redis = ConnectionMultiplexer.Connect(main); 

redis.ConnectionFailed += (src, args) => 
{ 
    if ((src as ConnectionMultiplexer).Configuration != backup) { 
     using (var writer = new StringWriter()) { 
      writer.Write(backup); 

      (src as ConnectionMultiplexer).Configure(writer); 
      /** 
       * Just for checking. It does not save 
       **/ 
      (src as ConnectionMultiplexer).GetDatabase().StringSet("aaa", "bbb"); 
     } 
    } 
}; 

Так что, когда мое главное соединение вниз, изменить конфигурацию, с помощью вызова (ЦСИ как ConnectionMultiplexer) .Configure (писатель) , так что ConnectionMultiplexer может использовать новую конфигурацию. Однако ConnectionMultiplexer продолжает использовать старый.

Вопрос: Как я могу изменить ConnectionMultiplexer.configuration в событии ConnectionFailed?

ответ

0

Не уверен, если это было бы приемлемо, точно не переключая конфигурации, но больше похож на восстановлении multiplixer

private static Lazy<IConnectionMultiplexer> _redisMux = new Lazy<ConnectionMultiplexer>(CreateMultiplexer); 
public static IConnectionMultiplexer Multiplexer { get { return _redisMux.Value; } } 

private const string Main = "192.168.XXX.YY:6379,abortConnect=false"; 
private const string Backup = "192.168.XXX.YY:6379,abortConnect=false"; 

private static string ActiveConfig = Main; 

private static ConnectionMultiplexer CreateMultiplexer() 
{ 
    var mux = ConnectionMultiplexer.Connect(ActiveConfig)); 
    mux.ConnectionFailed += OnConnectionFailed; 

    return mux; 
} 

[MethodImpl(MethodImplOptions.Synchronized)] 
private static void OnConnectionFailed(object sender, ConnectionFailedEventArgs e) 
{ 
    ActiveConfig = Backup; 

    try { Multiplexer.Dispose(); } catch { } 
    _redisMux = new Lazy<ConnectionMultiplexer>(CreateMultiplexer); 
} 
+0

Самый очевидный ответ, но мне нужно сохранить тот же экземпляр, потому что он распространяется по всему приложению. Возможно, событие может уведомить всех подписчиков, но некоторые части моего приложения не могут изменить свое первоначальное поведение, включая ссылку ConnectionMultiplexer. В любом случае, спасибо. –

+0

Я как-то ожидал вашего комментария. Я пытаюсь сделать что-то подобное, и я добираюсь до точки, где, по-моему, приложение должно иметь указатель на базу данных не на Multiplixer, и я работаю над этим рефакторингом ... Если я вернусь где-нибудь с безопасным переконфигурированием и повторным подключением, я поделюсь вопросом. Вопрос: хотя вы пробовали иметь оба узла в строке подключения и посмотреть, может ли maultiplixer обрабатывать сценарий сбоя подключения? –

+0

Если я установил оба соединения, я в конечном итоге столкнулся с проблемой нескольких мастеров. В этом случае StackExchange.redis использует концепцию TieBreaker для разрешения «основного» мастера. Я не уверен, что такая функциональность может безопасно решить мою проблему. Я проверю понедельник. –

2

Я посмотрел на source code библиотек, кажется, нет желаемой функциональности. Существует внутренний метод Reconfigure, но он пытается подключиться к другим серверам из конфигурации.

Я предлагаю вам использовать рефакторинг, если ваше приложение не очень велико. Создайте оболочку над ConnectionMultiplexer, передайте обертку объектам, где используется соединение. Мы используем метод GetConnection, который возвращает все ссылки на один объект. Все, кому требуется соединение, вызовет этот метод, нет необходимости хранить соединение. Внутри оболочки OnFailed подписаться на обработчик событий для создания нового подключения к резервному копированию.