我能想到的最接近的设计模式是责任链模式。
的想法是:
- 你建对象链(服务器)
- 让对象(服务器)处理请求
- 如果无法做到这一点,传递请求环比下跌
代码:
// 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