会话创建请求
- I/O 层接受来自客户端的请求,
zookeeper中每个NIOServerCnxn实例维护每一个客户端连接,客户端与服务端的所有通信都是由NIOServerCnxn负责的, 其负责统一接收来自客户端的所有请求, 并将请求从底层网络I/O中完整的读出来
- 判断是否是客户端会话创建请求
NIOServerCnxn在负责网络通信的同时, 自然也承担了客户端会话的载体, 每一个会话都会对应一个NIOServerCnxn载体,
- 反序列ConnectRequest请求
一旦确定当前客户端请求是"会话创建"请求, 服务端就可以对其进行反序列化, 并生成一个ConnectRequest请求实体
- 判断是否是ReadOnly客户端
- 检查客户端zxid
服务端zxid必定大于客户端zxid,如果小于服务端不接受客户端创建会话的请求
- 协商sessionTimeOut
会话创建
- 为客户端生成sessionID
9.注册会话
向sessiontracker中注册会话, 维护了两个重要的数据结构,sessionWithTimeout和sessionsById,前者根据sessionID保存了会话的超时时间, 而后者根据sessionID保存了所有会话实体
- 会话激活
分桶策略
- 生成会话密码
预处理
- 请求交付给zookeeper的PrepRequestProcessor处理
典型的责任链模式,
- 创建事务请求头
对于事务请求, zookeeper首先会为其创建事务请求头, 事务请求头是每个zookeeper事务请求非常重要的一部分
- 创建事务请求体
- 注册与激活会话
事务处理
- 将请求交给ProposalRequestProcessor处理器
三个子处理流程:- Sync流程
- Proposal流程
- Commit流程
16-1 Sync
使用SyncRequestProcessor处理器记录事务日志的过程,如果是事务请求会以事务日志的形式记录下来, Leader和Follower服务器的请求处理链路中都会有这个处理器, 完成事务日志记录后, 每个Follower都会向Leader服务器发送ACK消息
16-2 Proposal流程
1. 发起投票
2. 生成提议
3. 广播提议
4. 收集投票
5. 将请求放入 toBeApplied队列
6. 广播Commit消息
16-3: Commit流程
1. 请求交付给CommitProcessor处理器
2. 处理queuedRequests队列请求
3. 标记nextPending
4. 等待Proposal
5. 投票通过
6. 提交请求
commit流程会对比之前标记的nextPending和committedRequest队列中第一个请求是否一致, 然后交给下一个请求处理器: FinalRequestProcessor
事务应用
- 交付给FinalRequestProcessor处理器
请求流转到FinalRequestPorcessor处理后首先检查outstandingChanges队列中请求的有效性