Zookeeper 服务端初始化源码
1. 首先找到程序的启动类
Zookeeper 服务端启动需要执行命令: zkServer.sh start, 因此我们应该查看这个脚本, 在这个脚本中可以看到如下内容👀  主要有两个参数: ZOOMAIN: 显然这个 QuorumPeerMain 就是程序的入口啦😉 ZOOCFG: 输入参数, 配置文件, 它的值不在这个脚本中, 而是在 zkEnv.sh中  所以, 这个 QuorumPeerMain 就是程序的入口, 接下来就到进入源码, 查看这个类的 main() 方法吧😉  接下来让我们进入 initializeAndRun(String[] args) 方法吧👀
2. 解析参数
 args 是我们传入的 zoo.cfg, args.length的长度为1, 所以要进入 parse() 方法开始解析?  我们再进入 parseProperties() 方法?
 熟悉吗? 这些配置参数, 是我们在zoo.cfg中配置的😜, 让我们继续往下看源码  让我们进入 setupQuorumPeerConfig() 方法👀  还记得 myid 吗? myid是我们在安装 Zookeeper 集群时设置的, 在 dataDir路径下有一个名为 myid 的文件  到此为止, 解析参数就结束啦, 一个是解析 zoo.cfg 中的值, 另一个是解析 myid
让我们回退到 initializeAndRun() 方法, 查看接下来的源码👀👀
3.对过期快照执行删除(该功能默认关闭)
 snapRetainCount: 最少保留的快照个数, 默认3 purgeInterval: 默认0表示关闭过期快照删除功能
接下来我们进入 start() 方法👀  下面创建了一个 PurgeTask 对象, 那么这个 PurgeTask 对象又是什么呢? 我们进入 PurgeTask 类  最后我们发现, PurgeTask 原来是一个线程, 那么它被调度执行后就会进入 run() 方法, 我们继续查看 PurgeTask 的 run() 方法  再进入 purge() 方法  到此为止, 过期快照删除结束啦?, 让我们回到 initializeAndRun() 方法, 查看接下来的源码👀
4. 初始化NIO通信, 并绑定socket端口2181
进入 runFromConfig() 方法  进入 createFactory() 方法:  这个 zookeeper.serverCnxnFactory 配置在 zookeeperAdmin.md 文件中  在这里, 我们发现服务端的通信默认是 NIO 通信😉, 然后我们回退到 runFromConfig() 方法  点击 configure()方法, 这里参数传了一个 config.getClientPortAddress()  发现有3个实现, 然后我们选择NIO实现😉  到此为止, 初始化NIO通信以及绑定socket端口2181结束, zookeeper服务准备启动啦😁
5. 启动
返回 runFromConfig() 方法:  quorumPeer 即为zookeeper对象  zookeeper 启动!
流程图

|