架构

解决的问题:实现单个服务部署挂掉的问题

核心思想:借助zookeeper(分布式应用程序协调服务),临时节点的特性. 客户端服务断开链接,则这个节点自动移除。在不同客户端服务创建节点数据的时候创建成功的为master否则为salve,且保持watch不断开链接,当master客户端服务异常退出的时候从客户端服务自动创建成功数据升级为master服务。

方案如下:

使用的是.net 的zookeeper.Net插件,核心ZKClientFactory判断如下

public class ZKClientFactory
{
     private static bool IsMasterNode { get; set; } = false;
     private static ZooKeeper zk { get; set; }
     private static string ZookeeperIP = ConfigUtil.GetAppSetting("ZookeeperIP")?? "localhost";
     private static string ZookeeperPort = ConfigUtil.GetAppSetting("ZookeeperPort")??"2181";

     public static bool CheckNodeStatus(string name="/PlatformMonitor-Master")
     {
         ILog LOG = LogManager.GetLogger(typeof(ZKClient));
         try
         {
             if (zk == null || zk.State== States.CONNECTING)
             {
                 zk = new ZKClient().CreateClientWithAddress(ZookeeperIP+":"+ ZookeeperPort);
                 IsMasterNode = false;
             }
             string result = zk.Create(name, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.Ephemeral);
             IsMasterNode = true;
         }
         catch (NodeExistsException ex)
         {
             if(!IsMasterNode)
             {
                 IsMasterNode = false;
             }
             //LOG.Info(ex.ToString());
         }
         catch(Exception ex)
         {
             LOG.Info(ex.ToString());
         }
         return IsMasterNode;
     }
}

在任务调用的每次时间周期判断下主从节点,伪代码如下

public void Execute(IJobExecutionContext context)
{
      bool isMasterNode=ZKClientFactory.CheckNodeStatus();
      if (isMasterNode)
      {
          logger.Info("Job【Master】节点启动");
          EatException.Exec(() => {
              //具体执行的任务
          });
          logger.Info("Job【Master】节点作业完成");
      }
      else
      {
          logger.Info("Job【Slave】节点启动");
      }
}

Comment

This is just a placeholder img.