Server入口
Server的启动代码位于 zkServer.sh
文件中。
zkServer.sh
脚本同 /etc/init.d/
中的启动脚本比较类似,都是通过shell的case
命令解析指令执行。具体指令如下:
1. start
: 通过nohup后台启动org.apache.zookeeper.server.quorum.QuorumPeerMain
2. start-foreground
: 前台运行org.apache.zookeeper.server.quorum.QuorumPeerMain
3. stop
: 杀死通过start
启动的进程
4. restart
: 先后调用stop
和start
,起到重启的作用
5. status
: 通过org.apache.zookeeper.client.FourLetterWordMain
查看运行情况
6. upgrade
: 通过org.apache.zookeeper.server.upgrade.UpgradeMain
进行线上更新
7. print-cmd
: 输出启动start
的命令
启动逻辑
从zkServer.sh
中看到,ZooKeeper Server的入口类是QuorumPeerMain
。
在入口函数中,根据在 zoo.cfg
文件中配置的server个数,决定启动Standalone(单机)模式或是Cluster(集群)模式
如果在 zoo.cfg
文件中没有配置 server 则默认作为 Standalone 模式启动,并将启动参数传递给 ZooKeeperServerMain::main
,否则作为 Cluster 模式进行启动。
在本节中,暂时不考虑Cluster模式,只关心 Standalone 模式下的 Server 运行逻辑。
Standalone 模式的启动流程
如上所言,在Standalone模式下,QuorumPeerMain
会将启动参数传递给ZooKeeperServerMain::main
。
ZooKeeperServerMain::main
里,ZooKeeper在解析完成config文件后,调用runFromConfig
初始化Server。
public void runFromConfig(ServerConfig config) throws IOException {
final ZooKeeperServer zkServer = new ZooKeeperServer();
// Registers shutdown handler which will be used to know the
// server error or shutdown state changes.
final CountDownLatch shutdownLatch = new CountDownLatch(1);
zkServer.registerServerShutdownHandler( new ZooKeeperServerShutdownHandler(shutdownLatch));
cnxnFactory = ServerCnxnFactory.createFactory();
cnxnFactory.configure(config.getClientPortAddress(),
config.getMaxClientCnxns());
cnxnFactory.startup(zkServer);
shutdownLatch.await();
shutdown();
cnxnFactory.join();
if (zkServer.canShutdown()) {
zkServer.shutdown();
}
}
走读源码发现,cnxnFactory.startup
方法中启动了三个线程,分别是NIOServerCnxnFactory
(Runnable启动), PrepRequestProcessor
, SyncRequestProcessor
。
线程启动完毕后,进入shutdownLatch.await()
的等待状态, 阻塞主线程,避免程序退出。
退出逻辑在<