zookeeper java代碼實現master 選舉


1,master選舉使用場景及結構

現在很多時候我們的服務需要7*24小時工作,假如一台機器掛了,我們希望能有其它機器頂替它繼續工作。此類問題現在多采用master-salve模式,也就是常說的主從模式,正常情況下主機提供服務,備機負責監聽主機狀態,當主機異常時,可以自動切換到備機繼續提供服務(這里有點兒類似於數據庫主庫跟備庫,備機正常情況下只監聽,不工作),這個切換過程中選出下一個主機的過程就是master選舉。
對於以上提到的場景,傳統的解決方式是采用一個備用節點,這個備用節點定期給當前主節點發送ping包,主節點收到ping包后會向備用節點發送應答ack,當備用節點收到應答,就認為主節點還活着,讓它繼續提供服務,否則就認為主節點掛掉了,自己將開始行使主節點職責。如圖1所示:

2,master 選擇策略和zookeeper 分布式鎖的思路大致一樣

package com.aiyuesheng.controller;

import java.util.concurrent.CountDownLatch;

import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkException;
import org.I0Itec.zkclient.exception.ZkInterruptedException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class MyApplicationRunner implements ApplicationRunner {

    private CountDownLatch countDownLatch = null;

    String PATH = "/master";

    @Value("${server.port}")
    private String serverPort;

    ZkClient zkClient = new ZkClient("127.0.0.1:2181");

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("初始化.........");

        // 2,zookeeper實現監聽功能,當主節點掛了之后,繼續選舉
        if (zkClient != null) {
            // 1,在初始化過程中創建一個臨時節點,如果成功,則選為master節點
            election();
            // zookeeper 數據監聽的接口
            IZkDataListener izkDataListener = new IZkDataListener() {
                public void handleDataChange(String arg0, Object arg1) throws Exception {

                }
                public void handleDataDeleted(String path) throws Exception {
                    // 一直在監聽,節點有變化的時候原子量就是-1
                    if (countDownLatch != null) {
                        countDownLatch.countDown();
                    }
                }

            };
            //zkClient會去監聽
            zkClient.subscribeDataChanges(PATH, izkDataListener);
            if (zkClient.exists(PATH)) {
                countDownLatch = new CountDownLatch(1);
                try {
                    // 一直進行等待,等待監聽的路徑有變化
                    countDownLatch.await();
                    election();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            // 刪除監聽
            zkClient.unsubscribeDataChanges(PATH, izkDataListener);

        }

    }

    private void election() {
        try {
            zkClient.createEphemeral(PATH, serverPort);
            System.out.println("選舉成功");
            ZookeeperMaster.masterIsAlive = true;
        } catch (Exception e) {
            ZookeeperMaster.masterIsAlive = false;
        }
    }

}
public class ZookeeperMaster {
    
    public static boolean masterIsAlive = false;

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM