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方法太长了。精简了一下。仅仅留了骨架:
@Override public void run() { /// JMX... try { /* * Main loop */ while (running) { switch (getPeerState()) { case LOOKING: /// ... setCurrentVote(makeLEStrategy().lookForLeader()); /// ... break; case OBSERVING: try { setObserver(makeObserver(logFactory)); observer.observeLeader(); } catch (Exception e) { } finally { observer.shutdown(); setObserver(null); updateServerState(); } break; case FOLLOWING: try { setFollower(makeFollower(logFactory)); follower.followLeader(); } catch (Exception e) { } finally { follower.shutdown(); setFollower(null); updateServerState(); } break; case LEADING: try { setLeader(makeLeader(logFactory)); leader.lead(); setLeader(null); } catch (Exception e) { } finally { if (leader != null) { leader.shutdown("Forcing shutdown"); setLeader(null); } updateServerState(); } break; } } } finally { /// clear JMX } }
能够看出。仅仅要没有stop或者没有异常抛出。这个线程便一直在执行,没有兴许很多其它的操作了,所有在这个循环里。
到此为止,ZooKeeper集群中的这一个节点【Peer】启动完成。
从run()方法能够清晰的看到,ZooKeeper中的节点能够有四种状态:
- LOOKING
- OBSERVING
- FOLLOWING
- LEADING
当中,getPeerState()方法中state初始化为LOOKING,因此每个节点启动时的状态都是LOOKING。
下一步。就是參与投票,选出ZooKeeper集群的Leader,见下篇文章:ZooKeeper FastLeaderElection算法。