一、前言

  前面分析了LeaderZooKeeperServer,接着分析FollowerZooKeeperServer。

二、FollowerZooKeeperServer源码分析

  2.1 类的继承关系  

public class FollowerZooKeeperServer extends LearnerZooKeeperServer {}

  说明:其继承LearnerZooKeeperServer抽象类,角色为Follower。其请求处理链为FollowerRequestProcessor -> CommitProcessor -> FinalRequestProcessor。

  2.2 类的属性  

public class FollowerZooKeeperServer extends LearnerZooKeeperServer {
private static final Logger LOG =
LoggerFactory.getLogger(FollowerZooKeeperServer.class);
// 提交请求处理器
CommitProcessor commitProcessor; // 同步请求处理器
SyncRequestProcessor syncProcessor; /*
* Pending sync requests
*/
// 待同步请求
ConcurrentLinkedQueue<Request> pendingSyncs; // 待处理的事务请求
LinkedBlockingQueue<Request> pendingTxns = new LinkedBlockingQueue<Request>();
}

  说明:FollowerZooKeeperServer中维护着提交请求处理器和同步请求处理器,并且维护了所有待同步请求队列和待处理的事务请求队列。

  2.3 类的构造函数  

    FollowerZooKeeperServer(FileTxnSnapLog logFactory,QuorumPeer self,
DataTreeBuilder treeBuilder, ZKDatabase zkDb) throws IOException {
super(logFactory, self.tickTime, self.minSessionTimeout,
self.maxSessionTimeout, treeBuilder, zkDb, self);
// 初始化pendingSyncs
this.pendingSyncs = new ConcurrentLinkedQueue<Request>();
}

  说明:其首先调用父类的构造函数,然后初始化pendingSyncs为空队列。

  2.4 核心函数分析

  1. logRequest函数  

    public void logRequest(TxnHeader hdr, Record txn) {
// 创建请求
Request request = new Request(null, hdr.getClientId(), hdr.getCxid(),
hdr.getType(), null, null);
// 赋值请求头、事务体、zxid
request.hdr = hdr;
request.txn = txn;
request.zxid = hdr.getZxid();
if ((request.zxid & 0xffffffffL) != 0) { // zxid不为0,表示本服务器已经处理过请求
// 则需要将该请求放入pendingTxns中
pendingTxns.add(request);
}
// 使用SyncRequestProcessor处理请求(其会将请求放在队列中,异步进行处理)
syncProcessor.processRequest(request);
}

  说明:该函数将请求进行记录(放入到对应的队列中),等待处理。

  2. commit函数 

    public void commit(long zxid) {
if (pendingTxns.size() == 0) { // 没有还在等待处理的事务
LOG.warn("Committing " + Long.toHexString(zxid)
+ " without seeing txn");
return;
}
// 队首元素的zxid
long firstElementZxid = pendingTxns.element().zxid;
if (firstElementZxid != zxid) { // 如果队首元素的zxid不等于需要提交的zxid,则退出程序
LOG.error("Committing zxid 0x" + Long.toHexString(zxid)
+ " but next pending txn 0x"
+ Long.toHexString(firstElementZxid));
System.exit(12);
}
// 从待处理事务请求队列中移除队首请求
Request request = pendingTxns.remove();
// 提交该请求
commitProcessor.commit(request);
}

  说明:该函数会提交zxid对应的请求(pendingTxns的队首元素),其首先会判断队首请求对应的zxid是否为传入的zxid,然后再进行移除和提交(放在committedRequests队列中)。

  3. sync函数  

    synchronized public void sync(){
if(pendingSyncs.size() ==0){ // 没有需要同步的请求
LOG.warn("Not expecting a sync.");
return;
}
// 从待同步队列中移除队首请求
Request r = pendingSyncs.remove();
// 提交该请求
commitProcessor.commit(r);
}

  说明:该函数会将待同步请求队列中的元素进行提交,也是将该请求放入committedRequests队列中。

三、总结

  本篇学习了FollowerZooKeeperServer的源码,其核心是对待同步请求和待处理事务请求交由不同的请求处理器进行处理。也谢谢各位园友的观看~

【Zookeeper】源码分析之服务器(四)的更多相关文章

  1. zookeeper源码分析之四服务端(单机)处理请求流程

    上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...

  2. zookeeper源码分析之三客户端发送请求流程

    znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...

  3. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

  4. Zookeeper 源码分析-启动

    Zookeeper 源码分析-启动 博客分类: Zookeeper   本文主要介绍了zookeeper启动的过程 运行zkServer.sh start命令可以启动zookeeper.入口的main ...

  5. 手机自动化测试:appium源码分析之bootstrap四

    手机自动化测试:appium源码分析之bootstrap四   Orientation是调整屏幕方向的操作 package io.appium.android.bootstrap.handler; i ...

  6. 【Zookeeper】源码分析之服务器(四)之FollowerZooKeeperServer

    一.前言 前面分析了LeaderZooKeeperServer,接着分析FollowerZooKeeperServer. 二.FollowerZooKeeperServer源码分析 2.1 类的继承关 ...

  7. 【Zookeeper】源码分析之服务器(二)

    一.前言 前面阐述了服务器的总体框架,下面来分析服务器的所有父类ZooKeeperServer. 二.ZooKeeperServer源码分析 2.1 类的继承关系 public class ZooKe ...

  8. 【Zookeeper】源码分析之服务器(二)之ZooKeeperServer

    一.前言 前面阐述了服务器的总体框架,下面来分析服务器的所有父类ZooKeeperServer. 二.ZooKeeperServer源码分析 2.1 类的继承关系 public class ZooKe ...

  9. 【Zookeeper】源码分析之服务器(五)之ObserverZooKeeperServer

    一.前言 前面分析了FollowerZooKeeperServer,接着分析ObserverZooKeeperServer. 二.ObserverZooKeeperServer源码分析 2.1 类的继 ...

随机推荐

  1. 1.3.1. 新建Xcode项目并设置故事板(Core Data 应用程序实践指南)

    创建名为Grocery Dude的Single View程序,并按默认设置处理,不勾选Core Date 和 Git. 设计故事板: 选择Main.Storyboard 拖放一个 Table View ...

  2. 字符集 ISO-8859-1(2)

    HTML 支持的数学符号 结果 描述 实体名称 实体编号 ∀ for all ∀ ∀ ∂ part ∂ ∂ ∃ exists &exists; ∃ ∅ empty ∅ ∅ ∇ nabla ∇ ...

  3. Delphi的ListView自动排序

    private SortCol: Integer; SortWay: Integer; procedure TForm1.LVweColumnClick(Sender: TObject; Column ...

  4. HTML 5 Web 存储、应用程序缓存、Web Workers

    在客户端存储数据 HTML5 提供了两种在客户端存储数据的新方法: localStorage - 没有时间限制的数据存储 sessionStorage - 针对一个 session 的数据存储 之前, ...

  5. PayPal为什么从Java迁移到Node.js

    前言 大家都知道PayPal是另一家迁移到Node.js平台的大型公司,Jeff Harrell的这篇博文 Node.js at PayPal  解释了为什么从Java迁移出来的原因: 开发效率提高一 ...

  6. HDU5057(分块)

    Argestes and Sequence Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  7. TypeScript教程3

    1.快速回顾一下这JavaScript中的命名函数和匿名函数: 纯文本查看 复制代码 1 2 3 4 5 //Named functionfunction add(x, y) {     return ...

  8. Android中微信抢红包助手的实现

    参考(感谢作者):http://www.jianshu.com/p/cd1cd53909d7 http://blog.csdn.net/jiangwei0910410003/article/detai ...

  9. 理解Window和WindowManager

    Window表示一个窗口的概念,Window是一个抽象类,它的具体实现是PhoneWindow.创建一个Window,需要通过WindowManager即可完成,WindowManager是外界访问W ...

  10. [CSS3] 学习笔记-CSS3盒子样式

    1.盒子的类型 在CSS3中,使用display来定义盒子的类型,包括block,inline,inline-block类型.div元素和P元素,属于block类型,span元素和a元素,属于inli ...