2012-02-24 41 views
1

我有一個應用程序(說App1)通過.net遠程連接到另一個應用程序(App2)。 App2充當服務器。如果App2失效,App1將無法從App2中提取數據。我們計劃在另一臺機器上運行App2的實例(比如App2a),這樣如果App2關閉,App1會自動從App2a獲取數據。當App2再次運行時,App1需要從App2獲取數據。故障轉移機制尚未實現...請建議設計模式,以便將來可以爲App1添加任意數量的服務器實例以提取數據。建議設計模式實現故障轉移機制

謝謝

+0

故障轉移,複製,日誌傳送......不知道他們是「設計」模式,他們更概念。 – Nix 2012-02-24 18:52:56

+0

如果不知道客戶端如何與app1進行通信,我們無法回答這個問題。 – 2012-02-24 18:54:15

+0

使用udp,客戶端可以定期「ping」服務器。 – 2012-02-24 18:57:11

回答

1

我能想到的最接近的設計模式是責任鏈模式。

的想法是:

  1. 你建對象鏈(服務器)
  2. 讓對象(服務器)處理請求
  3. 如果無法做到這一點,傳遞請求環比下跌

代碼:

// Server interface 
public interface IServer 
{ 
    object FetchData(object param); 
} 

public class ServerProxyBase: IServer 
{ 
    // Successor. 
    // Alternate server to contact if the current instance fails. 
    public ServerBase AlternateServerProxy { get; set; } 

    // Interface 
    public virtual object FetchData(object param) 
    { 
     if (AlternateServerProxy != null) 
     { 
      return AlternateServerProxy.FetchData(param); 
     } 
     throw new NotImplementedException("Unable to recover"); 
    } 
} 

// Server implementation 
public class ServerProxy : ServerProxyBase 
{ 
    // Interface implementation 
    public override object FetchData(object param) 
    { 
     try 
     { 
      // Contact actual server and return data 
      // Remoting/WCF code in here... 
     } 
     catch 
     { 
      // If fail to contact server, 
      // run base method (attempt to recover) 
      return base.FetchData(param); 
     } 
    } 
} 

public class Client 
{ 
    private IServer _serverProxy; 
    public Client() 
    { 
     // Wire up main server, and its failover/retry servers 
     _serverProxy = new ServerProxy("mainserver:2712") 
     { 
      AlternateServerProxy = new ServerProxy("failover1:2712") 
      { 
       AlternateServerProxy = new ServerProxy("failover2:2712") 
      } 
     }; 
    } 
} 

本示例連接3臺服務器(mainserver,failover1,failover2)。

電話FetchData()將始終嘗試去mainserver

當它失敗時,它會嘗試failover1,然後是failover2,然後纔會拋出異常。

如果是對我,我不介意使用的東西快速和骯髒的,如:

public class FailoverServerProxy: IServer 
{ 
    private readonly List<ServerProxy> _servers; 
    public FailoverServerProxy RegisterServer(Server server) 
    { 
     _servers.Add(server); 
     return this; 
    } 

    // Implement interface 
    public object FetchData(object param) 
    { 
     foreach(var server in _servers) 
     { 
      try 
      { 
       return server.FetchData(param); 
      } 
      catch 
      { 
       // Failed. Continue to next server in list 
       continue; 
      } 
     } 

     // No more servers to try. No longer able to recover 
     throw new Exception("Unable to fetch data"); 
    }  
} 

public class Client 
{ 
    private IServer _serverProxy; 
    public Client() 
    { 
     // Wire up main server, and its failover/retry servers 
     _serverProxy = new FailoverServerProxy() 
          .RegisterServer("mainserver:2712") 
          .RegisterServer("failover1:2712") 
          .RegisterServer("failover2:2712");   
    } 

} 

我認爲它借用想法從其他模式,如外觀,策略和代理。

但我的動機是單純:

  1. 就已經存在的類的影響最小(即在Server類沒有額外的屬性)
  2. 分離的擔憂:
    • 爲中央級服務器的故障轉移/恢復邏輯。
    • 保持從客戶端/服務器隱藏故障轉移/恢復的實現。