先来看下ZooKeeper服务端的整体构架。
1.单机版服务器启动
ZooKeeper服务器的启动,大体分为以下5个步骤:配置文件解析、初始化数据管理器、初始化网络I/O管理器、数据恢复与对外服务。下图为单机版的服务器启动流程。
1.1 预启动
预启动步骤如下。
(1)统一由QuorumPeerMain作为启动类。
无论是单机版还是集群版,在启动ZooKeeper服务器时,在zkServer.cmd和zkServer.sh两个脚本中,都配置了使用org.apach.zookeeper.server.quorum.QuorumPeerMain作为启动类入口。
public class QuorumPeerMain {
private static final Logger LOG = LoggerFactory.getLogger(QuorumPeerMain.class);
private static final String USAGE = "Usage: QuorumPeerMain configfile";
protected QuorumPeer quorumPeer;
/**
* To start the replicated server specify the configuration file name on
* the command line.
* @param args path to the configfile
*/
public static void main(String[] args) {
QuorumPeerMain main = new QuorumPeerMain();
try {
main.initializeAndRun(args);
} catch (IllegalArgumentException e) {
LOG.error("Invalid arguments, exiting abnormally", e);
LOG.info(USAGE);
System.err.println(USAGE);
System.exit(2);
} catch (ConfigException e) {
LOG.error("Invalid config, exiting abnormally", e);
System.err.println("Invalid config, exiting abnormally");
System.exit(2);
} catch (Exception e) {
LOG.error("Unexpected exception, exiting abnormally", e);
System.exit(1);
}
LOG.info("Exiting normally");
System.exit(0);
}
protected void initializeAndRun(String[] args)
throws ConfigException, IOException
{
QuorumPeerConfig config = new QuorumPeerConfig();
if (args.length == 1) {
config.parse(args[0]); //解析配置文件zoo.cfg
}
// Start and schedule the the purge task //创建并启动历史文件清理器
DatadirCleanupManager purgeMgr = new DatadirCleanupManager(config
.getDataDir(), config.getDataLogDir(), config
.getSnapRetainCount(), config.getPurgeInterval());
purgeMgr.start();
if (args.length == 1 && config.servers.size() > 0) { //集群模式
runFromConfig(config);
} else { //单机模式
LOG.warn("Either no config or no quorum defined in config, running "
+ " in standalone mode");
// there is only server in the quorum -- run as standalone
ZooKeeperServerMa