这个类便是需要研究的类了,首先看一下这个类的解释
意思大概就是:用main方法来启动项目;一个参数是配置文件路径,配置文件格式是key value 最后都是一些配置文件解释。
图中方法
QuorumPeerConfig config = new QuorumPeerConfig();
if (args.length == 1) {
config.parse(args[0]);
}
重点看一下parse方法实现,
最后图中parseProperties重点看看
所以zk的启动第一步就是解析配置文件,这次在回到主类main方法中。
// Start and schedule the the purge task
DatadirCleanupManager purgeMgr = new DatadirCleanupManager(config
.getDataDir(), config.getDataLogDir(), config
.getSnapRetainCount(), config.getPurgeInterval());
purgeMgr.start();
DatadirCleanupManager 是一个文件清理工具类,start方法则是开启一个定时线程去转门清理log文件。
DatadirCleanupManager 类有 5 个属性,其中 snapDir 和 dataLogDir 分别表示数据快照地址以及日志数据的存放地址。而我们在日常工作中可以通过在 zoo.cfg 文件中配置 autopurge.snapRetainCount 和 autopurge.purgeInterval 这两个参数实现数据文件的定时清理功能,autopurge.purgeInterval 这个参数指定了清理频率,以小时为单位,需要填写一个 1 或更大的整数,默认是 0,表示不开启自己清理功能。autopurge.snapRetainCount 这个参数和上面的参数搭配使用,这个参数指定了需要保留的文件数目,默认是保留 3 个。
然后就是最后的启动了,runFromConfig方法;
public void runFromConfig(ServerConfig config) throws IOException {
http://LOG.info("Starting server");
FileTxnSnapLog txnLog = null;实现zk的持久化工具类
try {
// Note that this thread isn't going to be doing anything else,
// so rather than spawning another thread, we will just call
// run() in this thread.
// create a file logger url from the command line args
ZooKeeperServer zkServer = new ZooKeeperServer();内部初始化serverStats,serverStats
类用于统计 ZooKeeper 服务运行时的状态信息统计。主要统计的数据有服务端向客户端发送的响应包次数、接收到的客户端发送的请求包次数、服务端处理请求的延迟情况以及处理客户端的请求次数。在日常运维工作中,监控服务器的性能以及运行状态等参数很多都是这个类负责收集的。
txnLog = new FileTxnSnapLog(new File(config.dataLogDir), new File(
config.dataDir));工具类初始化配置文件参数
zkServer.setTxnLogFactory(txnLog);
zkServer.setTickTime(config.tickTime);
zkServer.setMinSessionTimeout(config.minSessionTimeout);
zkServer.setMaxSessionTimeout(config.maxSessionTimeout);
cnxnFactory = ServerCnxnFactory.createFactory();
cnxnFactory.configure(config.getClientPortAddress(),
config.getMaxClientCnxns());
cnxnFactory.startup(zkServer);
cnxnFactory.join();
if (zkServer.isRunning()) {
zkServer.shutdown();
}
} catch (InterruptedException e) {
// warn, but generally this is ok
LOG.warn("Server interrupted", e);
} finally {
if (txnLog != null) {
txnLog.close();
}
}
}
最后的代码基本是创建cnxnFactory,
static public ServerCnxnFactory createFactory() throws IOException {
String serverCnxnFactoryName =
System.getProperty(ZOOKEEPER_SERVER_CNXN_FACTORY);
if (serverCnxnFactoryName == null) {
serverCnxnFactoryName = NIOServerCnxnFactory.class.getName();创建nioserver
}
try {
return (ServerCnxnFactory) Class.forName(serverCnxnFactoryName)
.newInstance();
} catch (Exception e) {
IOException ioe = new IOException("Couldn't instantiate "
+ serverCnxnFactoryName);
ioe.initCause(e);
throw ioe;
}
}
在通过 ServerCnxnFactory 类制定了具体的 NIO 框架类后。ZooKeeper 首先会创建一个线程
Thread 类作为 ServerCnxnFactory 类的启动主线程。之后 ZooKeeper 服务再初始化具体的 NIO 类。这里请你注意的是,虽然初始化完相关的 NIO 类 ,比如已经设置好了服务端的对外端口,客户端也能通过诸如 2181 端口等访问到服务端,但是此时 ZooKeeper 服务器还是无法处理客户端的请求操作。这是因为 ZooKeeper 启动后,还需要从本地的快照数据文件和事务日志文件中恢复数据。这之后才真正完成了 ZooKeeper 服务的启动。