zookeeper实现master-slave选举(ZkClient实现)

所有客户端都往一个节点注册master节点,只有注册成功的可以成为master。

package master_slave;

import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkNodeExistsException;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class MasterSelector {
     

    private ZkClient zkClient;

    private final static String MASTER_PATH = "/master";

    private IZkDataListener dataListener;//注册节点变化的信息
    private UserCenter server;//其他节点
    private UserCenter master;//master服务器

    private static boolean isRunning = false;

    ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);


    public MasterSelector(UserCenter server,ZkClient zkClient) {
     
        System.out.println(server.toString());
        this.server = server;
        this.zkClient = zkClient;
        this.dataListener = new IZkDataListener() {
     
            @Override
            public void handleDataChange(String s, Object o) throws Exception {
     

            }

            @Override
            public void handleDataDeleted(String s) throws Exception {
     
                //节点如果被删除,触发选举操作
                chooseMaster();

            }
        };
    }

    public void start(){
     
        //开始选举
        if(!isRunning){
     
            isRunning=true;
            zkClient.subscribeDataChanges(MASTER_PATH,dataListener);
            chooseMaster();
        }
    }

    public void stop(){
     
        //停止选举
        if(isRunning){
     
            scheduledExecutorService.shutdown();
            zkClient.unsubscribeDataChanges(MASTER_PATH,dataListener);
            releaseMaster();
        }
    }

    //具体选主节点实现
    private void chooseMaster(){
     
        if (!isRunning) {
     
            System.out.println("当前服务没有启动。");
            return;
        }
        try {
     
            zkClient.createEphemeral(MASTER_PATH,server);
            master = server;
            System.out.println(master.getMc_name());

            //模拟master出现故障
            scheduledExecutorService.schedule(()->{
     
                releaseMaster();
            }, 5,TimeUnit.SECONDS);


        }catch (ZkNodeExistsException e){
     
            //表示master已经存在
            UserCenter userCenter = zkClient.readData(MASTER_PATH);
            if(userCenter==null) {
     
                chooseMaster();//再次获取master
            }else{
     
                master=userCenter;
            }
        }
    }

    private void releaseMaster(){
     
        //释放锁
        //判断当前是否为master
        if(checkIsMaster()){
     
            zkClient.delete(MASTER_PATH);
        }
    }

    private boolean checkIsMaster(){
     
        //判断是不是master
        UserCenter userCenter = zkClient.readData(MASTER_PATH);
        if(userCenter.getMc_name().equals(server.getMc_name())){
     
            master=server;
            return true;
        }
        return false;
    }


}

你可能感兴趣的:(zookeeper实现master-slave选举(ZkClient实现))