做模具做什么网站做外贸的人经常用什么网站
news/
2025/9/22 17:08:32/
文章来源:
做模具做什么网站,做外贸的人经常用什么网站,wordpress如何调用文章,pc端ui设计Zookeeper 架构理解
整体架构 Follower server 可以直接处理读请求#xff0c;但不能直接处理写请求。写请求只能转发给 leader server 进行处理。最终所有的写请求在 leader server 端串行执行。#xff08;因为分布式环境下永远无法精确地确认不同服务器不同事件发生的先后…Zookeeper 架构理解
整体架构 Follower server 可以直接处理读请求但不能直接处理写请求。写请求只能转发给 leader server 进行处理。最终所有的写请求在 leader server 端串行执行。因为分布式环境下永远无法精确地确认不同服务器不同事件发生的先后顺序ZooKeeper 集群中的所有节点的数据状态通过 ZAB 协议保持一致。ZAB 有两种工作模式 1崩溃恢复集群没有 Leader 角色内部在执行选举。 2原子广播集群有 Leader 角色Leader 主导分布式事务的执行向所有的 Follower 节点按照严格顺序广播事务。 3补充一点实际上ZAB 有四种工作模式分别是ELECTIONDISCOVERYSYNCHRONIZATIONBROADCAST。
Zookeeper 节点服务组件 Zookeeper 到底是 cp 还是 ap ?
严格意义上讲ZooKeeper 实现了 P 分区容错性、C 中的写入强一致性丧失的是 C 中的读取一致性。ZooKeeper 并不保证读取的是最新数据。如果客户端刚好链接到一个刚好没执行事务成功的节点也就是说没和 Leader 保持一致的 Follower 节点的话是有可能读取到非最新数据的。如果要保证读取到最新数据请使用 sync 回调处理。这个机制的原理是先让 Follower 保持和 Leader 一致然后再返回结果给客户端。关于 zookeeper 到底是 CP 还是 AP 的讨论zk 的 ap 和 cp 是从不同的角度分析的 1从一个读写请求分析保证了可用性不用阻塞等待全部 follwer 同步完成保证不了数据的一致性所以是ap。 2但是从zk架构分析zk在leader选举期间会暂停对外提供服务为啥会暂停因为zk依赖leader来保证数据一致性)所以丢失了可用性保证了一致性即cp。 再细点话这个 c 不是强一致性而是最终一致性。即上面的写案例数据最终会同步到一致只是时间问题。 3综上zk 广义上来说是 cp狭义上是 ap。
ZNode 数据模型
概述
ZooKeeper 的数据模型系统是一个类文件系统结构每个节点称之为 ZNode具体代码实现类是 DataNode。既不是文件夹也不是文件但是既具有文件夹的能力也具有文件的能力。
ZNode 分类
3.4.x 及以下版本ZNode 分为按照 临时/ 持久、 带序列编号/ 不带序列编号 分为 4 种
CreateMode.PERSISTENT 持久CreateMode.PERSISTENT_SEQUENTIAL 持久带序列编号CreateMode.EPHEMERAL 临时CreateMode.EPHEMERAL_SEQUENTIAL 临时带序列编号 临时节点的下面不能挂载子节点。临时节点只能作为叶子节点其生命周期和会话绑定。 3.5.x 及以上版本加入以下三种CONTAINER容器节点其最后一个子对象被删除时该容器将在一段时间后删除。PERSISTENT_WITH_TTLzookeeper的扩展类型如果znode在给定的TTL内没有被修改它将在没有子节点时被删除。PERSISTENT_SEQUENTIAL_WITH_TTL同上是不过是带序号的。
Zookeeper 不适合写入大量数据的原因
因为 ZooKeeper 系统内部每个节点都会做数据同步在执行写请求的时候事实上就是原子广播。待写入数据越大原子广播的效率就越低成功难度也越大。所有的请求都是严格的顺序串行执行, 这个 ZooKeeper 集群在某一个时刻只能执行一个事务如果上一个事务执行耗时则会阻塞后面的请求的执行。正因为每个节点都会存储一份完整的 ZooKeeper 系统数据所以如果系统数据过大甚至超过了单个 Follower 的存储能力了系统服务大受影响甚至崩溃。ZooKeeper 的设计初衷就不是为了给用户提供一个大规模数据存储服务而是提供了一个为了解决一些分布式问题而需要进行一些状态存储的数据模型系统。
Watcher 监听机制 注册监听的三种方式
zk.getData(znodePath, watcher); // 关注节点的数据变化
zk.exists(znodePath, watcher); // 关注节点的存在与否的状态变化
zk.getChildren(znodePath, watcher); // 关注节点的子节点个数变化触发监听的三种方式
zk.setData(); // 更改节点数据触发监听
zk.create(); // 创建节点
zk.delete(); // 删除节点四种事件类型
NodeCreated // 节点被创建
NodeDeleted // 节点被删除
NodeDataChanged // 节点数据发生改变
NodeChildrenChanged // 节点的子节点个数发生改变Zookeeper 应用场景
Zookeeper 作为分布式协调服务最常见应用场景是分布式锁和集群管理。例如 HDFS NameNode 高可用模式YARN ResourceManager 高可用模式HBase RegionServer 的管理与元数据存储Flink 主节点组件 ResourceManager、JobManager、Dispatcher 的高可用模式等等。
分布式锁 集群管理 Zookeeper 源码剖析
Zookeeper 基础组件详解
Zookeeper 序列化机制
序列化的 API 主要在 zookeeper-jute 子项目中。
class ZNode implements Record{int id;String name;// 反序列化void deserialize(InputArchive archive, String tag){archive.readBytes();archive.readInt();}// 序列化void serialize(OutputArchive archive, String tag)
}Zookeeper 持久化机制
简介
1、数据模型DataTree DataNode 2、持久化机制FileTxnSnalLog TxnLog SnapLog 3、zk数据库ZKDataBase DataTree FileTxnSnapLog 补充1 1、每个节点上都保存了整个系统的所有数据 ( leader 存储了数据所有的 follower 节点都是 leader 的副本节点)。 2、每个节点上的都把数据放在磁盘一份放在内存一份。 补充2 1、DataNode znode 系统中的一个节点的抽象。 2、DataTree znode 系统的完整抽象。 3、ZKDataBase 负责管理 DataTree处理最基本的增删改查的动作执行 DataTree 的相关快照和恢复的操作。
API 介绍
第一组主要是用来操作日志的如果客户端往 ZooKeeper 中写入一条数据则记录一条日志 TxnLog接口读取事务性日志的接口 FileTxnLog实现 TxnLog 接口添加了访问该事务性日志的 API 第二组拍摄快照当内存数据持久化到磁盘 Snapshot接口类型持久层快照接口 FileSnap实现 Snapshot 接口负责存储、序列化、反序列化、访问快照 第三组两个成员变量TxnLog 和 SnapShot FileTxnSnapLog封装了 TxnLog 和 SnapShot 第四组工具类 Util工具类提供持久化所需的API
伪代码 Demo
class ZKDataBase{protected DataTree dataTree;protected FileTxnSnapLog snapLog;
}class DataTree{
//根节点private static final String rootZookeeper /;// 所有节点的 路径 和 节点抽象的 映射private final NodeHashMap nodes new NodeHashMapImpl(digestCalculator){private final ConcurrentHashMapString, DataNode nodes;}
}public class DataNode implements Record {byte[] data;private SetString children null;
}class FileTxnSnapLog{TxnLog txnLog;SnapShot snapLog;
}// 实现类
interface TxnLog{void rollLog() throws IOException;boolean append(TxnHeader hdr, Record r) throws IOException;boolean truncate(long zxid) throws IOException;void commit() throws IOException;
}
// 实现类
interface SnapShot{long deserialize(DataTree dt, MapLong, Integer sessions) throws IOException;void serialize(DataTree dt, MapLong, Integer sessions, File name, boolean fsync) throws IOException;
}Zookeeper 网络通信机制 建立连接时只允许服务器ID较大者去连服务器ID较小者小ID服务器去连大ID服务器会被拒绝。
ZooKeeper 源码阅读大纲
Zookeeper 节点类型 ZooKeeper 服务节点启动
1、集群启动脚本zkServer.sh start 2、集群启动的启动类的代码执行QuorumPeerMain.main() 3、冷启动数据恢复从磁盘恢复数据到内存zkDatabase.loadDatabase() 4、选举startLeaderElection() QuorumPeer.lookForLeader() 5、同步follower.followLeader() observer.observerLeader()
QuorumPeerMain 结构简图 ZooKeeper QuorumPeerMain 启动
启动过程概览
入口QuorumPeerMain 的 main 方法
解析配置 读取 zoo.cfg 得到 Properties 对象解析这个对象得到各种配置设置到 QuorumPeerConfig解析 server. 开头的各项配置获取 allMembers, votingMembers, observerMembers 集合然后构建 QruoumMaj 实例解析 myid 启动删除旧快照文件的定时任务启动 QuorumPeer 创建 NIO 服务端相关组件和线程创建 QuorumPeer 实例然后把 QuorumPeerConfig 中的各种配置设置到 QuorumPeer调用 start 方法启动 冷启动数据恢复启动 NIO 服务端启动 AdminServerstartLeaderElection 为选举做准备启动 JVM 监视器启动 QuorumPeer 线程进入 ZAB 工作模式 QuorumPeer.run()quorumPeers 变量被一分为三存储在 QuorumMaj 的内部allMembers, votingMembers, observingMembers
loadDataBase
// 入口方法
QuorumPeer.loadDataBase(){zkDb.loadDataBase(){// 冷启动的时候从磁盘恢复数据到内存snapLog.restore(dataTree,...){// 第一件事从快照恢复snapLog.deserialize(dt, sessions){deserialize(dt, sessions, ia){SerializeUtils.deserializeSnapshot(dt, ia, sessions){dt.deserialize(ia, tree);}}}// 第二件事从操作日志恢复fastForwardFromEdits(dt, sessions, listener){while(true) {// 恢复执行一条事务processTransaction(hdr, dt, sessions, itr.getTxn()){// 恢复执行一条事务dt.processTxn(hdr, txn){// 创建一个znodecreateNode 或者 deleteNode}} }}}}
}ZooKeeper 选举算法 FastLeaderElection 实例化难点
背景知识
1所有的节点有选举权和被选举权一上线就是 LOOKING 状态当选举结束了之后有选举权中的角色会变量另外两种Leader, Follower相应的状态变为 LEADING、FOLLOWING。 2需要发送选票选票是 Vote 对象广播到所有节点。事实上关于选票和投票的类型有四种 Vote 选票 Notificatioin 接收到的投票 Message 放入投票队列的选票 ToSend 待发送的选票 还有一个特殊的中间对象ByteBuffer —— NIO 的一个 API 3当每个 zookeeper 服务器启动好了之后第一件事就是发起投票如果是第一次发起投票都是去找 leader如果发现有其他 zookeeper 返回给我 leader 的信息那么选举结束。 4在进行选票发送的时候每个 zookeeper 都会为其他的 zookeeper 服务节点生成一个对应的 SendWorker 和一个 ArrayBlockingQueueArrayBlockingQueue 存放待发送的选票SendWorker 从队列中获取选票执行发送。还有一个线程叫做 ReceiveWorker 真正完整从其他节点接收发送过来的投票。 整个图总结一下分成两个部分 创建 QuorumCnxManager 创建了 recvQueue 队列 创建了 queueSendMap 创建了 senderWorkerMap 创建了 Listener 线程 创建 FastLeaderElection 创建了 sendqueue 队列 创建了 recvqueue 队列 创建了 WorkerSender 线程 创建了 WorkerReceiver 线程 终于启动了选举入口方法 FastLeaderElection.lookForLeader();
选票交换
选举客户端入口方法FastLeaderElection.lookForLeader() 中会调用 QuorumCnxManager 的 connectAll 方法进而对每个节点调用 connectOne 方法。 选举服务端入口方法QuorumCnxManager 内部类 ListenerHandler 的 ServerSocket.accept() 方法处理连接请求校验 sid 是否满足大于本节点 sid满足则创建对应的 SendWorker、RecvWorker、CircularBlockingQueue 用于发送和接受选票。
lookForLeader() 执行选举
QuorumPeer.run(){while(true){switch(getPeerState()) {case LOOKING:// 选举入口 makeLEStrategy() FastLeaderElection// 默认每间隔 2 秒 (tickTime) 执行一轮投票setCurrentVote(makeLEStrategy().lookForLeader());break;case OBSERVING:// 选举结束observer 跟 leader 进行状态同步setObserver(makeObserver(logFactory));observer.observeLeader();break;case FOLLOWING:// 选举结束没有成为 leader 的服务器成为 follower保持和 leader 的同步setFollower(makeFollower(logFactory));follower.followLeader();break;case LEADING:// 选举结束其中一个 participant 成为 leader进入领导状态setLeader(makeLeader(logFactory));leader.lead();break;}}
}ZooKeeper 消息同步
ZAB 的四种工作状态
ELECTION开始选举当前 Server 进入找 Leader 状态Vote currentVote lookForLeader() DISCOVERY当选举得出了结果开始进入发现认同阶段当超过半数 Follower 认同该 Leader意味着选举真正结束 SYNCHRONIZATION经过确认有超过半数节点都追随了刚推举出来的 Leader 节点 BROADCAST当有超过半数的 Follower 完成了和 Leader 的状态同步之后进入消息广播状态正常对外提供服务
ZooKeeper 的 Follower 和 Leader 的状态同步图解 右图详细架构如下
关于同步过程中的两种方式
1快照同步Leader 直接把最新的快照文件这个快照文件必然包含了 Leader 的所有数据直接通过网络发送给 Follower。 2差异化同步在确认同步方式的时候如果得到的结果不是快照同步则同时把要同步的数据变成Proposal Commit 消息放到 队列中队列中的数据的形态
DIFF Proposal Commit Proposal Commit Proposal Commit Proposal Commit NEWLEADER当 Follower 接收到 NEWLEADER 消息的时候意味着 Follower 已经接收到了需要同步的所有数据。
标准的 10 步骤详细介绍
1Follower 发送 FOLLOWERINFO 消息给 Leader信息中包含 Follower 的 AcceptedEpoch。 2Leader 在接收到 Follower 的 FOLLOWERINFO 消息的时候返回一个 LEADERINFO 消息给 Follower信息中包含 Leader 的 AcceptedEpoch。 3Follower 给 Leader 返回一个 ACKEPOCH 消息表示已经接收到 Leader 的 AcceptedEpoch 了。Leader 需要等待有超过半数的 Follower 发送回 ACKEPOCH 消息有超过半数节点在追随相同的 Leader 节点则选举结束开始进入同步阶段。 4Leader 根据 Follower 发送过来的 epoch 信息给 Follower 计算同步方式同步方式有可能是 DIFF, SNAP, TRUNC 的其中之一。计算得到的同步方式消息放入到 LearnerHandler 的 queuedPackets 队列中跟后面计算出来的待同步的分布式事务日志一起执行发送。同步方式的计算逻辑位于 LearnerHandler 的 syncFollower 方法中。 5如果同步方式是 DIFF则获取到需要同步的分布式事务的 PROPOSAL 和 COMMIT 日志也放入 LearnerHandler 的 queuedPackets 队列中如果 同步方式是 SNAP则先写入一个 SNAP 消息给 Follower然后把快照文件发送过 Follower 进行快照同步 6通过 startSendingPackets() 方法启动一个匿名线程执行 LearnerHandler 的 queuedPackets 队列中的数据包发送。 7当该同步的数据queuedPackets 队列中的 PROPOSAL 和 COMMIT 日志或者 SNAP 方式的快照文件都发送完毕之后Leader 给 Follower 发送一个 NEWLEADER 消息表示所有待同步数据已经发送完毕。 8Follower 在接收到 Leader 发送过来的 NEWLEADER 消息就必然得知要和 Leader 进行同步的日志数据都已经发送过来了自己也都执行成功了则可以给 Leader 发送过一个 ACK 反馈 9Leader 需要等待集群中有超过半数的节点发送 ACK 反馈过来如此集群启动成功Leader 给发送过了 ACK 的 Follower Server 发送一个 UPTODATE 的消息表示集群已经启动成功。Leader 和 Follower 都启动各自的一些必备基础服务可以开始对外提供服务了。 10Follower 接收到 Leader 的 UPTODATE 消息即表示集群启动正常Follower 可以正常对外提供服务Follower 再给 Leader 返回一个 ACK。
注意 3 个细节
1Leader 和 Follower 之间是有心跳的。如果维持心跳的节点数不超过集群半数节点了则集群不能正常对外提供服务了。全部进入 LOOKING 状态。 2Leader 通过 syncFollower() 方法来计算和 Follower 的同步方式。关于什么情况分析得到什么同步方式的细节需要了解清楚。 3Leader 和 Follower 在集群正常启动成功之后需要启动一些基础服务比如 SessionTracker 和 RequestProcessor 等。
Follower 的状态同步源码实现
大体分为三个大部分
进入 DISCOVERY 状态确认 Leader 并且建立和 Leader 的链接。进入 SYNCHRONIZATION 状态执行和 Leader 的状态同步。进入 BROADCAST 状态不停的接收 Leader 广播过来的 Proposal 执行。
Follower 的状态同步源码实现
基本上分为四个大步骤
Leader 进入 DISCOVERY 状态首先加载数据获取 Leader 的一些基本信息并且拍摄一次快照。Leader 创建 LearnerCnxAcceptor内部创建 BIO 服务端用来接受 Follower 的链接请求用来执行同步。 1首先接收 Follower 的 ACKEPOCH 消息如果接收超过集群半数则 Leader 确认然后进入同步状态等待有超过半数节点完成和 Leader 的状态同步 2Leader 在完成超过半数 Follower 节点的同步的时候就开始启动 Leader 的一些基础服务了也说明 ZooKeeper 集群完成正常启动成功了 3Leader 进入 BROADCAST 状态QuorumPeer 线程维护和 Follower 的心跳在 Leader 的 lead 方法最后LearnerHandler 线程对对应的 Follower 提供服务。
ZooKeeper 服务启动
Leader 中的 ZooKeeperServer 启动
在 Leader 的 lead() 方法的最后也就是 Leader 完成了和集群过半 Follower 的同步之后就会调用 startZkServer() 来启动必要的服务主要包括
SessionTrackerRequestProcessor更新 Leader ZooKeeperServer 的状态
Leader.lead(){startZkServer(){zk.startup(){// ZooKeeperServer 启动super.startup(){startupWithServerState(State.RUNNING);}// ZK Container ZNode 定时清除任务if(containerManager ! null) {containerManager.start();}}}
}注Leader 中聚合了 ZooKeeperServer 的子类 LeaderZooKeeperServer。ZooKeeperServer 内部枚举类 State 共有 4 个实例INITIAL, RUNNING, SHUTDOWN, ERROR。
Follow 中的 ZooKeeperServer 启动
Follower 也是一样的。在完成了和 Leader 的状态同步之后也就是接收到 Leader 发送过来的 NEWLEADER 消息的时候就会首先拍摄快照然后调用 zk.startupWithoutServing() 来启动 Follower 必要的一些基础服务包括
SessionTrackerRequestProcessor更新 Leader ZooKeeperServer 的状态
Learner.syncWithLeader(long newLeaderZxid){// 创建 SessionTrackerzk.createSessionTracker();// 启动一些各种服务zk.startupWithoutServing(){startupWithServerState(State.INITIAL);}
}Leader 中的 ZooKeeperServer 启动
ZooKeeperServer.startupWithServerState(State state){// 创建和启动 SessionTrackerif(sessionTracker null) {createSessionTracker();}startSessionTracker();// 初始化 RequestProcessorsetupRequestProcessors();// 其他各项基础服务startRequestThrottler();registerJMX();startJvmPauseMonitor();registerMetrics();// TODO_MA 注释 更新状态为 RUNNINGsetState(state);// 解除其他线程的阻塞notifyAll();
}其中最为重要的两件事有两件
创建和启动 SessionTracker 会话管理器。初始化各种 RequestProcessor。
ZooKeeper SessionTracker 启动和工作机制详解
在 Leader 启动的时候Leader 会创建 LeaderSessionTracker在 Follower 启动的时候内部会创建一个 LearnerSessionTracker。SessionTracker 的内部都有 globalSessionTracker 和 localSessionTracker 之分但是无论如何都是通过 SessionTrackerImpl 和 ExpiryQueue 来完成 Session 管理的。
Leader 和 Follower 的 RequestProcessor 初始化
Leader 的 setupRequestProcessors() 方法的核心逻辑 Leader RequestProcessor 详解
LeaderRequestProcessorLeader 调用链开始, 这个处理器主要是处理本地 session 相关的请求。 PrepRequestProcessor请求预处理器能够识别出当前客户端请求是否是事务请求。对于事务请求PrepRequestProcessor 处理器会对其进行一系列预处理如创建请求事务头、事务体、会话检查、ACL 检查和版本检查等。ProposalRequestProcessor事务投票处理器。Leader 服务器事务处理流程的发起者。接收到非事务请求不做什么处理会直接将请求转发到 CommitProcessor接收到事务请求除了将请求转发到 CommitProcessor 外还会根据请求类型创建对应的 Proposal 提议并广播给所有 Follower 进行投票。另外它还会将事务请求交付给 SyncRequestProcessor 进行事务日志的记录。CommitProcessor事务提交处理器。对于非事务请求该处理器会直接将其交付给下一级处理器处理对于事务请求其会等待集群内针对 Proposal 的投票直到该 Proposal 可被提交利用 CommitProcessor每个服务器都可以很好地控制对事务请求的顺序处理。ToBeAppliedRequestProcessor该处理器有一个 toBeApplied 队列用来存储那些已经被 CommitProcessor 处理过的可被提交的 Proposal。其会将这些请求交付给 FinalRequestProcessor 处理器处理待其处理完后再将其从 toBeApplied 队列中移除。FinalRequestProcessorFinalRequestProcessor 用来进行客户端请求返回之前的操作包括创建客户端请求的响应针对事务请求该处理还会负责将事务应用到内存数据库中去SyncRequestProcessor事务日志记录处理器。负责将事务持久化到磁盘上。实际上就是将事务数据按顺序追加到事务日志中同时会触发 ZooKeeper 进行数据快照。AckRequestProcessor负责在 SyncRequestProcessor 完成事务日志记录后向 Proposal 的投票收集器发送 ACK 反馈以通知投票收集器当前服务器已经完成了对该 Proposal 的事务日志记录。
Follower 的 RequestProcessor 初始化
不管是 follower 还是 leader, 不管是读请求还是写请求, RP 处理链的入口都是 firstProcessor。 Follower 的 setupRequestProcessors() 方法的核心逻辑 Follower RequestProcessor 详解
FollowerRequestProcessor识别当前请求是否是事务请求若是那么 Follower 就会将该请求转发给 Leader 服务器Leader 服务器是在接收到这个事务请求后就会将其提交到请求处理链按照正常事务请求进行处理。CommitProcessor同 Leader 的 CommitProcessorFinalRequestProcessor同 Leader 的 FinalRequestProcessorSyncRequestProcessor同 Leader 的 SyncRequestProcessorSendAckRequestProcessor其承担了事务日志记录反馈的角色在完成事务日志记录后会向 Leader 服务器发送 ACK 消息以表明自身完成了事务日志的记录工作。当 Leader 服务器接收到足够确认消息来提交这个提议时Leader 就会发送提交事务消息给追随者(同时也会发送 INFORM 消息给观察者服务器)。当接收到提交事务消息时追随者就通过 CommitProcessor 处理器进行处理。
ZooKeeper 客户端初始化 SendThread 内部保存了一个 ClientCnxnSocketNIO相当于一个 NIO 的客户端负责和 ZooKeeper 的 ServerCnxnFactory 中启动的服务端建立连接然后负责消费 outgoingQueue 中的消息执行请求发送。EventThread 线程消费 waitingEvents 队列调用 processEvent(event) 负责处理服务端返回回来的消息事件异步回调等。客户端状态枚举类实例
public enum States {CONNECTING,ASSOCIATING,CONNECTED,CONNECTEDREADONLY,CLOSED,AUTH_FAILED,NOT_CONNECTED;
}客户端实际请求地址方式random —— 打乱随机获取。
ZooKeeper 服务端初始化
NIOServerCnxnFacotry 内部首先启动一个 AcceptorThread, 多个 SelectorThread一个线程池WorkerThread。每次接收到一个客户端链接请求在服务端会生成一个 ServerCnxn 的组件这个对象的内部就是封装了一个 SocketChannel专门对某个 client 执行服务。 在 ZooKeeper 的客户端 ClientCnxn 初始化的时候是由内部的 SendThread 发起连接请求给服务端建立连接然后服务端的会给当前的客户端生成一个 ServerCnxn一个客户端就会有一个对应的 ServerCnxn相当于 ServerCnxn 和 ClientCnxn 是一一对应的关系。而且当服务端 生成好了 ServerCnxn 之后还会给当前这个连接创建一个 Session通过 Session 来管理这个链接。 默认 selector 线程个数处理器个数/ 2 开根号 跟1 求最大值 默认 worker 线程个数处理器个数 * 2 默认 worker 线程超时时间5s 启动过程
第一步创建服务端 NIOServerCnxnFactory第二步对 NIOServerCnxnFactory 进行初始化第三步启动 NIOServerCnxnFactory 内部的各种工作线程 AcceptThread 负责接受链接请求建立连接SelectorThread 负责 IO 读写WorkerService 负责请求处理ConnectionExpirerThread 线程负责链接超时管理
客户端和服务端链接建立全流程分析 小结
关于 ZooKeeper 的会话创建流程
第一步ZooKeeper 对象内部的 ClientCnxn 内部的 HostProvider 会随机选一个我们提供的地址然后委托给 ClientCnxnSocket 去建立和 ZooKeeper 服务端之间的 TCP 链接。第二步SendThreadClient 的网络发送线程构造出一个 ConnectRequest 请求代表客户端与服务器创建一个会话。同时Zookeeper 客户端还会进一步将请求包装成网络 IO 的 Packet 对象放入请求发送队列 outgoingQueue 中去等待发送。ClientCnxnSocket 从 outgoingQueue 中取出 Packet 对象将其序列化成 ByteBuffer 后向服务器进行发送。服务端的 SessionTracker 为该会话分配一个 sessionId并发送响应。Client 收到响应后此时此刻便明白自己没有初始化因此会用 readConnectResult 方法来处理请求。ServerCnxnSocket 会对接受到的服务端响应进行反序列化得到 ConnectResponse 对象并从中获取到 Zookeeper 服务端分配的会话 SessionId。通知 SendThread更新 Client 会话参数比如重要的 connectTimeout 并更新 Client 状态另外通知地址管理器 HostProvider 当前成功链接的服务器地址。注意点 对于 Leader-Follower 通信心跳消息由 Leader 发送给 Follower 对于 Server-Client 通信心跳消息由 Client 发送给 Server。
zookeeper 中的设计模式
watcher 模板方法模式 requestProcessors 职责链模式netty 的 pipeline 也用到了类似的思想 zookeeper ZKDataBase 用到了 外观模式能力增强、组合模式子节点管理
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/909750.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!