lanicc

ZooKeeper源码阅读——启动流程

2021-05-07

分析zk启动流程

从zk的启动脚本中可以看到zk的启动类是
org.apache.zookeeper.server.quorum.QuorumPeerMain

从QuorumPeerMain.initializeAndRun方法可以看到

1
2
3
4
5
6
7
if (args.length == 1 && config.isDistributed()) {
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
ZooKeeperServerMain.main(args);
}

单机版的zk启动,走的是ZooKeeperServerMain.main(args);这条路

单机模式

时序图(在idea中使用插件SequenceDiagram,Call depth设为3,从ZooKeeperServerMain#main开始生成时序图)
ZooKeeperServerMain_main.png

关键流程分析

  • 1.1.4.4 创建FileTxnSnapLog: FileTxnSnapLog数据管理器,用来操作事务日志和快照的工具类
  • 1.1.4.6 创建ZooKeeperServer: ZooKeeperServer是一个简单的单机版的zkServer,提供处理request请求的能力
  • 1.1.4.10 创建AdminServer: 创建zkAdminServer
  • 1.1.4.12 创建ServerCnxnFactory: ServerCnxnFactory是zk中客户端与服务端的网络IO管理器
  • 1.1.4.18 创建ContainerManager: ContainerManager用来管理容器节点的清理工作

ZooKeeperServer

1.4.1.1.6

1
final ZooKeeperServer zkServer = new ZooKeeperServer(jvmPauseMonitor, txnLog, config.tickTime, config.minSessionTimeout, config.maxSessionTimeout, config.listenBacklog, null, config.initialConfig);

参数依次是:

  • jvmPauseMonitor
  • txnLog: 数据管理器,用来操作事务日志和快照的工具类
  • tickTime: 通常被用来作为心跳、超时时间,官方文档上的解释是:the length of a single tick, which is the basic time unit used by ZooKeeper, as measured in milliseconds. It is used to regulate heartbeats, and timeouts. For example, the minimum session timeout will be two ticks.
  • maxSessionTimeout: 最小的session过期时间,默认是2个tickTime
  • maxSessionTimeout: 最大的session过期时间,默认是20个tickTime
  • clientPortListenBacklog: ZooKeeper服务端等待处理的请求队列最大长度
  • initialConfig: 启动时的配置文件内容

AdminServer

1.4.1.1.10 adminServer = AdminServerFactory.createAdminServer()

AdminServer 的实现有两个,可以看下面的继承关系图
AdminServer继承关系图
启动时,AdminServerFactory 会根据配置 zookeeper.admin.enableServer 选择AdminServer

DummyAdminServer是一个空实现,不作任何事情,使用这个实现相当于是关闭了AdminServer功能
JettyAdminServer是基于Jetty Server实现的,是默认的AdminServer

ServerCnxnFactory

创建

1.1.4.12 cnxnFactory = ServerCnxnFactory.createFactory()
ServerCnxnFactory的实现有两个,分别是基于NIO的实现和基于Netty的实现
ServerCnxnFactory
可以通过配置选择使用,配置项zookeeper.serverCnxnFactory,默认使用NIO的实现

配置

1.1.4.13 cnxnFactory.configure(config.getClientPortAddress(), config.getMaxClientCnxns(), config.getClientPortListenBacklog(), false)

参数依次是:

  • 暴露的服务端口号
  • 一个IP最大的客户端连接数
  • TCP listen backlog
  • 是否启用SSL(NIO不支持该选项)

启动

1.1.4.14 cnxnFactory.startup(zkServer)
内部会启动监听,接收客户端连接,并且启动zkServer

ContainerManager

创建

1.1.4.18

1
2
3
4
5
6
7
containerManager = new ContainerManager(
zkServer.getZKDatabase(),
zkServer.firstProcessor,
Integer.getInteger("znode.container.checkIntervalMs", (int) TimeUnit.MINUTES.toMillis(1)),
Integer.getInteger("znode.container.maxPerMinute", 10000),
Long.getLong("znode.container.maxNeverUsedIntervalMs", 0)
);

参数依次是:

  • zkDatabase
  • zkServer的第一个请求处理器
  • 检查节点的间隔时间
  • 一次中最大删除节点的数量,为了避免依次删除太多
  • 一个容器节点没有子节点的最长保留时间

启动

1.1.4.19 containerManager.start()
内部会启用一个线程,定时检查需要删除的节点,并将删除请求发送给zkServer的请求处理器

集群模式