一、前言

  前面分析了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. linux 同步机制之complete【转】

    转自: http://blog.csdn.net/wealoong/article/details/8490654 在Linux内核中,completion是一种简单的同步机制,标志"thi ...

  2. HDU-1754-I Hate It(线段树,简单,不过好像有点问题)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1754 题目不难,不过开始我犯了一个低级错误,输入n,m,m代表操作的数目,我没有写了,写代码的时候,就 ...

  3. TIMESTAMP和DATETIME哪个好

    日期范围 TIMESTAMP 支持从'1970-01-01 00:00:01′ 到 '2038-01-19 03:14:07′ UTC. 这个时间可能对目前正在工作的人来说没什么问题,可以坚持到我们退 ...

  4. jQuery 处理TextArea

    jQuery 处理TextArea: $('#btn001').click(function(e) { console.log("btn001Click"); var cmt = ...

  5. Android的文件存储

    //文件的写入 String content1 = edt_file.getText().toString(); //用于文件的写操作 FileOutputStream fos=null; //缓冲输 ...

  6. 初识SuperSocket

    有一些企业由于以前使用的操作系统是被淘汰的操作系统,例如OpenVMS.现需要将针对openvms开发的通讯程序进行移植到现在的windows操作系统上,通过一段时间的了解,现在需要花时间去找商业性的 ...

  7. JavaScript中this的指向问题

    this是面向对象语言中一个重要的关键字,理解并掌握该关键字的使用对于我们代码的健壮性及优美性至关重要.而javascript的this又有区别于Java.C#等纯面向对象的语言,这使得this更加扑 ...

  8. Intellij IDEA 建立文件夹目录问题

    问题: NEW一个package常出现文件夹层次问题 解决: 1.选中当前文件夹(要在该文件夹下添加): 2.右击此处: 3.添加即可. 链接:http://stackoverflow.com/que ...

  9. ArcGIS API for JavaScript 4.2学习笔记[2] 显示3D地图

    3D地图又叫场景. 由上一篇可知, require入口函数的第一个参数是字符串数组 ["esri/Map", "esri/views/MapView", &qu ...

  10. jquery 高级 学习笔记

    --jquery 和 原生js可以共存,但不能混用.jquery 可以通过get()方法 转换为原生js. $("#div1").get(0).innerHTML; get() 需 ...