2012-02-24 65 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. 分离的担忧:
    • 为中央级服务器的故障转移/恢复逻辑。
    • 保持从客户端/服务器隐藏故障转移/恢复的实现。