我能想到的最接近的設計模式是責任鏈模式。
的想法是:
- 你建對象鏈(服務器)
- 讓對象(服務器)處理請求
- 如果無法做到這一點,傳遞請求環比下跌
代碼:
// 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");
}
}
我認爲它借用想法從其他模式,如外觀,策略和代理。
但我的動機是單純:
- 就已經存在的類的影響最小(即在
Server
類沒有額外的屬性)
- 分離的擔憂:
- 爲中央級服務器的故障轉移/恢復邏輯。
- 保持從客戶端/服務器隱藏故障轉移/恢復的實現。
故障轉移,複製,日誌傳送......不知道他們是「設計」模式,他們更概念。 – Nix 2012-02-24 18:52:56
如果不知道客戶端如何與app1進行通信,我們無法回答這個問題。 – 2012-02-24 18:54:15
使用udp,客戶端可以定期「ping」服務器。 – 2012-02-24 18:57:11