zookeeper原理之Leader选举的getView 的解析流程和ZkServer服务启动的逻辑
以下说说Leader选举的getView的解析流程
1 2 3 | public Map<Long,QuorumPeer.QuorumServer> getView() { return Collections.unmodifiableMap( this .quorumPeers); } |
getView 里面实际上返回的是一个 quorumPeers,就是参与本次投票的成员有哪些。这个属性在哪里赋值的呢?我们又得回到 runFromConfig 方法中
QuorumPeerMain.runFromConfig
设置了一个值为 config.getServers()
1 2 3 | //… quorumPeer.setQuorumPeers(config.getServers()); //… |
config 这个配置信息又是通过在 initializeAndRun 方法中初始化的,
1 2 3 4 5 6 | protected void initializeAndRun(String[] args) throws ConfigException, IOException { QuorumPeerConfig config = new QuorumPeerConfig(); if (args.length == 1) { config.parse(args[0]); } } |
QuorumPeerConfig.parse
这里会根据一个外部的文件去进行解析,然后其中有一段是这样,解析对应的集群配置数据放到 servers 这个集合中
1 2 3 4 5 6 7 | } else if (key.startsWith( "server." )) { int dot = key.indexOf( '.' ); long sid = Long.parseLong(key.substring(dot + 1)); String parts[] = splitWithLeadingHostname(value); if ((parts.length != 2) && (parts.length != 3) && (parts.length !=4)) { LOG.error(value + " does not have the form host:port or host:port:port " + " or host:port:port:type" ); } |
ZkServer 服务启动的逻辑
在讲 leader 选举的时候,有一个 cnxnFactory.start()方法来启动 zk 服务,这块具体做了什么呢?我们来分析看看
QuorumPeerMain.runFromConfig
在 runFromConfig 中,有构建了一个 ServerCnxnFactory
1 2 3 4 5 6 7 8 9 10 11 12 | public void runFromConfig(QuorumPeerConfig config) throws IOException { //… LOG.info( "Starting quorum peer" ); try { ServerCnxnFactory cnxnFactory = ServerCnxnFactory.createFactory(); cnxnFactory.configure(config.getClientPortAddress(), config.getMaxClientCnxns()); //… quorumPeer.setCnxnFactory(cnxnFactory); //…并且将这个 factory 设置给了 quorumPeer 的成员属性 } } |
这个很明显是一个工厂模式,基于这个工厂类创建什么呢? 打开createFactory 方法看看就知道了
ServerCnxnFactory.createFactory
这个方法里面是根据 ZOOKEEPER_SERVER_CNXN_FACTORY 来决定创建 NIO server 还是 Netty Server而默认情况下,应该是创建一个 NIOServerCnxnFactory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | static public ServerCnxnFactory createFactory() throws IOException { String serverCnxnFactoryName = System.getProperty(ZOOKEEPER_SERVER_CNXN_FACTORY); if (serverCnxnFactoryName == null ) { serverCnxnFactoryName = NIOServerCnxnFactory. class .getName(); } try { ServerCnxnFactory serverCnxnFactory = (ServerCnxnFactory) Class.forName(serverCnxnFactoryName) .getDeclaredConstructor().newInstance(); LOG.info( "Using {} as server connection factory" , serverCnxnFactoryName); return serverCnxnFactory; } catch (Exception e) { IOException ioe = new IOException( "Couldn't instantiate " + serverCnxnFactoryName); ioe.initCause(e); throw ioe; } } |
QuorumPeer.start
因此,我们再回到 QuorumPeer.start()方法中,cnxnFactory.start(),应该会调用 NIOServerCnxnFactory 这个类去启动一个线程
1 2 3 4 5 6 | public synchronized void start() { loadDataBase(); cnxnFactory.start(); startLeaderElection(); super.start(); } |
NIOServerCnxnFactory.start
这里通过 thread.start 启动一个线程,那 thread 是一个什么对象呢?
1 2 3 4 5 6 | public void start() { // ensure thread is started once and only once if (thread.getState() == Thread.State.NEW) { thread.start(); } } |
NIOServerCnxnFactory.configure
thread 其实构建的是一个 zookeeperThread 线程,并且线程的参数为 this,表示当前 NIOServerCnxnFactory 也是实现了线程的类,那么它必须要重写run 方法,因此定位到 NIOServerCnxnFactory.run。
到此,NIOServer 的初始化以及启动过程就完成了。并且对 2181 的这个端口进行监听。一旦发现有请求进来,就执行相应的处理即可。这块后续在分析数据同步的时候再做详细了解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Thread thread; @Override public void configure(InetSocketAddress addr, int maxcc) throws IOException { configureSaslLogin(); thread = new ZooKeeperThread( this , "NIOServerCxn.Factory:" + addr); thread.setDaemon( true ); maxClientCnxns = maxcc; this .ss = ServerSocketChannel.open(); ss.socket().setReuseAddress( true ); LOG.info( "binding to port " + addr); ss.socket().bind(addr); ss.configureBlocking( false ); ss.register(selector, SelectionKey.OP_ACCEPT); } |
分类:
zookeeper
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具