2017-01-16 2 views
3

기본적으로 나는 "DON'T DO THIS" 센티넬 시나리오를 가지고 있습니다. 센티넬은 시나리오에서 안전하지 않기 때문에, 나는 .Configure (작가) (ConnectionMultiplexer 같은 SRC)를 호출하여, 내 주요 연결이 다운되었을 때 다음과 같은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는 새로운 구성을 사용할 수 있습니다. 그러나 ConnectionMultiplexer는 이전 버전을 계속 사용합니다.

질문 : ConnectionFailed 이벤트에서 ConnectionMultiplexer.configuration을 어떻게 변경합니까? 즉 허용 될 경우

답변

0

확실하지, 아니 정확히 설정을 전환하지만 더처럼 라이브러리의 source code에서 보았다 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

나는 당신의 코멘트를 기대하고 있었다. 나는 비슷한 것을하려고 노력하고있다. 그리고 App이 Multiplixer가 아닌 데이터베이스에 대한 포인터를 가져야한다고 생각하는 지점에 이르고있다. 그리고 나는이 리펙토링을 위해 일하고있다. 안전한 재구성을하고 어딘가에 다시 연결하게되면 공유 할 것입니다.하지만 연결 문자열에 두 호스트를 모두 가지고 시도했는지, maultiplixer가 연결 실패 시나리오를 처리 할 수 ​​있는지 확인 했습니까? –

+0

두 연결을 모두 설정하면 여러 주인 문제가 발생합니다. 이 경우 StackExchange.redis는 TieBreaker 개념을 사용하여 "주"마스터를 해결합니다. 이러한 기능이 내 문제를 안전하게 해결할 수 있는지 여부는 확실하지 않습니다. 월요일에 확인해 볼게. –

2

을 재건, 더 원하는 기능이없는 것 같다. 내부 방법 재구성이 있지만 구성에서 다른 서버에 연결을 시도합니다.

응용 프로그램이 그리 크지 않은 경우 리팩터링을 제안합니다. ConnectionMultiplexer에 랩퍼를 만들고, 연결이 사용되는 오브젝트에 랩퍼를 전달하십시오. 단일 객체의 모든 링크를 반환하는 GetConnection 메서드를 래핑합니다. 연결이 필요한 모든 사용자는이 메서드를 호출하므로 연결을 저장할 필요가 없습니다. 래퍼 내부에서 OnFailed는 이벤트 처리기에 가입하여 백업에 대한 새 연결을 만듭니다.