【Zookeeper】源碼分析之服務器(三)之LeaderZooKeeperServer


一、前言

  前面分析了ZooKeeperServer源碼,由於QuorumZooKeeperServer的源碼相對簡單,於是直接分析LeaderZooKeeperServer。

二、LeaderZooKeeperServer源碼分析

  2.1 類的繼承關系 

public class LeaderZooKeeperServer extends QuorumZooKeeperServer {}

  說明:LeaderZooKeeperServer繼承QuorumZooKeeperServer抽象類,其會繼承ZooKeeperServer中的很多方法。

  2.2 類的屬性  

public class LeaderZooKeeperServer extends QuorumZooKeeperServer {
    // 提交請求處理器
    CommitProcessor commitProcessor;
}

  說明:其只有一個CommitProcessor類,表示提交請求處理器,其在處理鏈中的位置位於ProposalRequestProcessor之后,ToBeAppliedRequestProcessor之前。

  2.3 類的構造函數

    LeaderZooKeeperServer(FileTxnSnapLog logFactory, QuorumPeer self,
            DataTreeBuilder treeBuilder, ZKDatabase zkDb) throws IOException {
        super(logFactory, self.tickTime, self.minSessionTimeout,
                self.maxSessionTimeout, treeBuilder, zkDb, self);
    }

  說明:其直接調用父類QuorumZooKeeperServer的構造函數,然后再調用ZooKeeperServer的構造函數,逐級構造。

  2.4 核心函數分析

  1. setupRequestProcessors函數  

    protected void setupRequestProcessors() {
        // 創建FinalRequestProcessor
        RequestProcessor finalProcessor = new FinalRequestProcessor(this);
        // 創建ToBeAppliedRequestProcessor
        RequestProcessor toBeAppliedProcessor = new Leader.ToBeAppliedRequestProcessor(
                finalProcessor, getLeader().toBeApplied);
        // 創建CommitProcessor
        commitProcessor = new CommitProcessor(toBeAppliedProcessor,
                Long.toString(getServerId()), false);
        // 啟動CommitProcessor
        commitProcessor.start();
        // 創建ProposalRequestProcessor
        ProposalRequestProcessor proposalProcessor = new ProposalRequestProcessor(this,
                commitProcessor);
        // 初始化ProposalProcessor
        proposalProcessor.initialize();
        // firstProcessor為PrepRequestProcessor
        firstProcessor = new PrepRequestProcessor(this, proposalProcessor);
        // 啟動PrepRequestProcessor
        ((PrepRequestProcessor)firstProcessor).start();
    }

  說明:該函數表示創建處理鏈,可以看到其處理鏈的順序為PrepRequestProcessor -> ProposalRequestProcessor -> CommitProcessor -> Leader.ToBeAppliedRequestProcessor -> FinalRequestProcessor。

  2. registerJMX函數 

    protected void registerJMX() {
        // register with JMX
        try {
            // 創建DataTreeBean
            jmxDataTreeBean = new DataTreeBean(getZKDatabase().getDataTree());
            // 進行注冊
            MBeanRegistry.getInstance().register(jmxDataTreeBean, jmxServerBean);
        } catch (Exception e) {
            LOG.warn("Failed to register with JMX", e);
            jmxDataTreeBean = null;
        }
    }

  說明:該函數用於注冊JMX服務,首先使用DataTree初始化DataTreeBean,然后使用DataTreeBean和ServerBean調用register函數進行注冊,其源碼如下 

    public void register(ZKMBeanInfo bean, ZKMBeanInfo parent)
        throws JMException
    {
        // 確保bean不為空
        assert bean != null;
        String path = null;
        if (parent != null) { // parent(ServerBean)不為空
            // 通過parent從bean2Path中獲取path
            path = mapBean2Path.get(parent);
            // 確保path不為空
            assert path != null;
        }
        // 補充為完整的路徑
        path = makeFullPath(path, parent);
        if(bean.isHidden())
            return;
        // 使用路徑來創建名字
        ObjectName oname = makeObjectName(path, bean);
        try {
            // 注冊Server
            mBeanServer.registerMBean(bean, oname);
            // 將bean和對應path放入mapBean2Path
            mapBean2Path.put(bean, path);
            // 將name和bean放入mapName2Bean
            mapName2Bean.put(bean.getName(), bean);
        } catch (JMException e) {
            LOG.warn("Failed to register MBean " + bean.getName());
            throw e;
      

  說明:可以看到會通過parent來獲取路徑,然后創建名字,然后注冊bean,之后將相應字段放入mBeanServer和mapBean2Path中,即完成注冊過程。

  3. unregisterJMX函數  

    protected void unregisterJMX() {
        // unregister from JMX
        try {
            if (jmxDataTreeBean != null) {
                // 取消注冊
                MBeanRegistry.getInstance().unregister(jmxDataTreeBean);
            }
        } catch (Exception e) {
            LOG.warn("Failed to unregister with JMX", e);
        }
        jmxDataTreeBean = null;
    }

  說明:該函數用於取消注冊JMX服務,其會調用unregister函數,其源碼如下 

    public void unregister(ZKMBeanInfo bean) {
        if(bean==null)
            return;
        // 獲取對應路徑
        String path=mapBean2Path.get(bean);
        try {
            // 取消注冊
            unregister(path,bean);
        } catch (JMException e) {
            LOG.warn("Error during unregister", e);
        }
        // 從mapBean2Path和mapName2Bean中移除bean
        mapBean2Path.remove(bean);
        mapName2Bean.remove(bean.getName());
    }

  說明:unregister與register的過程恰好相反,是移除bean的過程。

三、總結

  本篇學習了LeaderZooKeeperServer的源碼,其源碼非常簡單,主要涉及到注冊和取消注冊服務,其大部分邏輯可以直接使用ZooKeeperServer中的方法,也謝謝各位園友的觀看~


免責聲明!

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



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