wolong 发表于 2015-9-7 08:59:55

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方法太长了,精简了一下,只留了骨架:
  



view plaincopy

[*]@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算法。
  

  转自ZooKeeper启动过程
页: [1]
查看完整版本: ZooKeeper启动过程