ZooKeeper服務端啓動過程——單機模式

本文對單機模式下,ZooKeeper服務端的啓動過程進行介紹

相關的類

  • QuorumPeerMain:服務端啓動的入口類
  • DatadirCleanupManager:歷史文件清理器
  • ZooKeeperServerMain:單機模式下的啓動類

QuorumPeerMain類的main方法,如下:

public static void main(String[] args) {
        QuorumPeerMain main = new QuorumPeerMain();
        try {
            main.initializeAndRun(args);
        }catch(){
      //TODO
        }
}

在initializeAndRun(args)方法中進行一系列的初始化工作

protected void initializeAndRun(String[] args) throws ConfigException, IOException, AdminServerException
    {
        QuorumPeerConfig config = new QuorumPeerConfig();
        if (args.length == 1) {
            config.parse(args[0]);
        }
        // 定時,啓動歷史文件的清理器
        DatadirCleanupManager purgeMgr = new DatadirCleanupManager(config
                .getDataDir(), config.getDataLogDir(), config
                .getSnapRetainCount(), config.getPurgeInterval());
        purgeMgr.start();
    // 對啓動方式進行判斷,集羣模式還是單機模式
        if (args.length == 1 && config.isDistributed()) {
        //集羣模式的啓動入口
            runFromConfig(config);
        } else {
        //單機模式的啓動方式
            ZooKeeperServerMain.main(args);
        }
    }

至此,單機模式的啓動方式完成了一下幾個步驟:

  • 啓動QuorumPeerMain類,執行main方法
  • 解析配置文件,加載配置參數
  • 啓動定時的歷史文件清理器DatadirCleanupManager
  • 啓動ZooKeeperServerMain類,執行其main方法

到這一步,ZooKeeper服務端的啓動任務已經轉移到了ZooKeeperServerMain中,下面我們就看看在main方法中都進行了哪些操作。

 public static void main(String[] args) {
        ZooKeeperServerMain main = new ZooKeeperServerMain();
        try {
            main.initializeAndRun(args);
        }catch(){
        //TODO
        }
}

在initializeAndRun(args)完成的工作如下所示:

//註冊log4j JMX mbeans
ManagedUtil.registerLog4jMBeans();
//從配置文件中啓動服務端
runFromConfig(config);

在服務端的啓動過程,涉及到的類有:

  • FileTxnSnapLog:這是ZooKeeper上層服務器和底層數據存儲之間的一個對接層,提供了一系列操作數據文件的接口,這些數據文件包括事務日誌文件和快照數據文件,入參爲數據快照目錄dataDir和事務日誌目錄dataLogDir
  • ServerStats:這是一個服務端的統計器,統計服務器運行的狀態信息,關於這個類將在後面進行介紹
  • ZooKeeperServerShutdownHandler:當服務器shutdown之後的處理類,有一個CountDownLatch的同步器控制
  • ServerCnxnFactory
  • ZooKeeperServer
  • ContainerManager

ZooKeeperServerMain類中的runFromConfig(ServerConfig config)執行邏輯

主要代碼如下:

public void runFromConfig(ServerConfig config) throws IOException, AdminServerException {
    //實例化一個ZooKeeper服務端的數據管理器,提供一些接口操作事務日誌文件、快照數據文件
    FileTxnSnapLog txnLog = null; 
    //dataLogDir和dataDir是配置文件中的事務日誌文件、數據快照文件的目錄
    txnLog = new FileTxnSnapLog(config.dataLogDir, config.dataDir);
    //實例化一個ZooKeeperServer對象
    final ZooKeeperServer zkServer = new ZooKeeperServer(txnLog,config.tickTime, config.minSessionTimeout, config.maxSessionTimeout, null);
    //設置ServerStats
    txnLog.setServerStats(zkServer.serverStats());
    //向ZooKeeperServer對象註冊一個ZooKeeperServerShutdownHandler
    final CountDownLatch shutdownLatch = new CountDownLatch(1);
    zkServer.registerServerShutdownHandler(new  ZooKeeperServerShutdownHandler(shutdownLatch));
    //得到一個ServerCnxnFactory對象,反射機制,具體看createFactory()方法
    cnxnFactory = ServerCnxnFactory.createFactory();
    //啓動cnxnFactory, 在startup()中,進行主要的邏輯
    cnxnFactory.startup(zkServer);
}

cnxnFactory.startup(zkServer)是服務端啓動的主要邏輯所在,該方法採用的是模板模式。代碼如下:

public void startup(ZooKeeperServer zkServer) throws IOException, InterruptedException {
        startup(zkServer, true);
    }

其真正的處理邏輯是由startup(zkServer, true)負責完成的。實現類NIOServerCnxnFactory中的代碼如下:

@Override
public void startup(ZooKeeperServer zks, boolean startServer)
            throws IOException, InterruptedException {
        //啓動服務端的一些線程,後面在慢慢研究
        start(); 
        //設置ZooKeeperServer對應的ServerCnxnFactory
        setZooKeeperServer(zks);
        if (startServer) {
        //從FileTxnSnapLog中初始化數據
            zks.startdata();
            //啓動ZooKeeperServer,完成諸如
            //創建並啓動會話管理器SessionTracker
            //初始化ZooKeeper的請求處理鏈路
            //註冊JMX服務
            //將ZooKeeperServer服務端的狀態設置位running
            //通知所有阻塞在這裏的線程
            zks.startup();
        }
 }

所以,在ZooKeeperServerMain這個類中,主要完成一系列初始化的配置+ServerCnxnFactory的runFromConfig。

具體的執行邏輯

  • 初始化一個ZooKeeper服務端的數據管理器FileTxnSnapLog,作爲事務日誌文件和快照數據文件的管理器
  • 解析配置參數,並根據FileTxnSnapLog對象來實例化一個ZooKeeperServer對象
  • 爲ZooKeeperServer註冊一個ZooKeeperServerShutdownHandler
  • 通過反射機制,得到一個ServerCnxnFactory對象
  • 調用ServerCnxnFactory對象的startup()方法。該方法的具體執行邏輯見上文中方法的代碼。

ServerCnxnFactory對象的startup()方法的執行邏輯
主要完成線程的初始化,以及ZooKeeperServer對象的一些初始化工作,流程如下:

  • 調用ServerCnxnFactory的start方法,完成服務端網絡連接的一些線程的問題(具體後文詳細介紹,請持續關注)
  • ZooKeeper服務端的數據文件的恢復
  • 初始化並啓動會話管理器,SessionTracker
  • 初始化ZooKeeper服務端的請求處理鏈,典型的責任鏈模式
    1. PrepRequestProcessor
    2. SyncRequestProcessor
    3. FinalRequestProcessor
  • 註冊JMX服務
  • 設置狀態爲running,然後notifyAll
發佈了45 篇原創文章 · 獲贊 5 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章