ZooKeeper启动过程

ZooKeeper启动过程

1.如何启动

zkServer.sh【Linux】或 zkServer.cmd【Windows】

以zkServer.cmd为例(zkServer.sh中内容太多):

可以清晰的看出:调用了QuorumPeerMain这个类,传的参数为%ZOOCFG%【在zkEnv.cmd中定义,就是zoo.cfg】。

到QuorumPeerMain类中一看,果然有个main方法,且接受一个参数【配置文件路径】:

当然,接受的参数不是一个也没关系,只不过就不能集群了,只能以单机模式运行。仅当接受一个参数作为配置文件路径,且此配置文件没有设置为单机模式,才会开启ZooKeeper集群启动过程【上图120行,runFromConfig】。

2.启动过程源码分析

runFromConfig:

可以看出,程序转移到了QuorumPeer,首先设置一系列zoo.cfg中的属性值,而后start,QuorumPeer继承了Thread类,自然转到了QuorumPeer.run()。

run方法太长了,精简了一下,只留了骨架:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. @Override  
  2.    public void run() {  
  3.     /// JMX...  
  4.        try {  
  5.            /* 
  6.             * Main loop 
  7.             */  
  8.            while (running) {  
  9.                switch (getPeerState()) {  
  10.                case LOOKING:  
  11.                    /// ...  
  12.                 setCurrentVote(makeLEStrategy().lookForLeader());  
  13.                 /// ...  
  14.                    break;  
  15.                case OBSERVING:  
  16.                    try {  
  17.                        setObserver(makeObserver(logFactory));  
  18.                        observer.observeLeader();  
  19.                    } catch (Exception e) {  
  20.                    } finally {  
  21.                        observer.shutdown();  
  22.                        setObserver(null);    
  23.                        updateServerState();  
  24.                    }  
  25.                    break;  
  26.                case FOLLOWING:  
  27.                    try {  
  28.                        setFollower(makeFollower(logFactory));  
  29.                        follower.followLeader();  
  30.                    } catch (Exception e) {  
  31.                    } finally {  
  32.                       follower.shutdown();  
  33.                       setFollower(null);  
  34.                       updateServerState();  
  35.                    }  
  36.                    break;  
  37.                case LEADING:  
  38.                    try {  
  39.                        setLeader(makeLeader(logFactory));  
  40.                        leader.lead();  
  41.                        setLeader(null);  
  42.                    } catch (Exception e) {  
  43.                    } finally {  
  44.                        if (leader != null) {  
  45.                            leader.shutdown("Forcing shutdown");  
  46.                            setLeader(null);  
  47.                        }  
  48.                        updateServerState();  
  49.                    }  
  50.                    break;  
  51.                }  
  52.            }  
  53.        } finally {  
  54.            /// clear JMX  
  55.        }  
  56.    }  


可以看出,只要没有stop或者没有异常抛出,这个线程便一直在运行,没有后续更多的操作了,全部在这个循环里。

到此为止,ZooKeeper集群中的这一个节点【Peer】启动完毕。

从run()方法可以清晰的看到,ZooKeeper中的节点可以有四种状态:

  • LOOKING
  • OBSERVING
  • FOLLOWING
  • LEADING

其中,getPeerState()方法中state初始化为LOOKING,因此每一个节点启动时的状态都是LOOKING。

下一步,就是参与投票,选出ZooKeeper集群的Leader,见下篇文章:ZooKeeper FastLeaderElection算法。

转自ZooKeeper启动过程

原文地址:https://www.cnblogs.com/catWang/p/4120671.html