Zookeeper(六)服务器

zkServer.cmd中声明 首先启动QuorumPeerMain

set ZOOMAIN=org.apache.zookeeper.server.quorum.QuorumPeerMain

服务器启动

预启动--QuorumPeerMain

  1. 解析配置文件zoo.cfg:配置运行时的基本参数tickTime、dataDir、clientPort
  2. 创建并启动历史文件清除器:对事务日志及快照数据文件定时清理
  3. 如果是集群情况下,再次解析配置文件
  4. 单机情况下,创建服务器实例
public class QuorumPeerMain {
//args:配置文件zoo.cfg的路径
protected void initializeAndRun(String[] args)
throws ConfigException, IOException, AdminServerException {
QuorumPeerConfig config = new QuorumPeerConfig();
if (args.length == 1) {
//1. 解析配置文件:配置运行时的基本参数tickTime、dataDir、clientPort
config.parse(args[0]);
}
//2.创建并启动历史文件清除器:对事务日志及快照数据文件定时清理
DatadirCleanupManager purgeMgr = new DatadirCleanupManager(config
.getDataDir(), config.getDataLogDir(), config
.getSnapRetainCount(), config.getPurgeInterval());
purgeMgr.start();
//3. 如果是集群情况下 再次解析配置文件
if (args.length == 1 && config.isDistributed()) {
runFromConfig(config);
} else {
//3.2. 单机情况下 standalone 创建服务器实例
LOG.warn("Either no config or no quorum defined in config, running "
+ " in standalone mode");
ZooKeeperServerMain.main(args);
}
}
}

初始化--ZooKeeperServerMain

public class ZooKeeperServerMain {
protected void initializeAndRun(String[] args)
throws ConfigException, IOException, AdminServerException{
cnxnFactory = ServerCnxnFactory.createFactory();
cnxnFactory.startup(zkServer);
}
}
单机模式
  1. 初始化数据管理器FileTxnSnapLog:根据配置解析出快照文件路径和数据文件路径

  2. 初始化服务器ZooKeeperServer:根据配置的tickTime,minSessionTimeout等

  3. 通过系统属性确定ServerCnxnFactory的继承实现类是NIOServerCnxnFactory还是NettyServerCnxnFactory

  4. 创建ServerCnxnFactory:配置客户端连接端口,最大连接数,最大挂起连接数

  5. 启动

    • 设置内部数据库,恢复会话和数据
    • 创建并开启会话管理sessionTracker
    • 初始化请求处理链,处理器以责任链方式链接,并启动顺序处理请求的线程
    • 注册JMX:Zookeeper会将服务器运行时的一些信息以JMX的方式暴露给外部。
    • 设置服务器状态为运行中
public class NettyServerCnxnFactory {
public void startup(ZooKeeperServer zks, boolean startServer)
throws IOException, InterruptedException {
start();
setZooKeeperServer(zks);
if (startServer) {
zks.startdata();
zks.startup();
}
}
}

ZooKeeperServer

public class ZooKeeperServer implements SessionExpirer, ServerStats.Provider {
//会话跟踪
protected SessionTracker sessionTracker;
//数据管理器:管理事务日志文件和快照数据文件
private FileTxnSnapLog txnLogFactory = null;
//zk的内部数据库
private ZKDatabase zkDb;
private ResponseCache readResponseCache;
//对客户端请求的处理
protected RequestProcessor firstProcessor;
//服务器状态
protected volatile State state = State.INITIAL; public synchronized void startup() {
if (sessionTracker == null) {
createSessionTracker();
}
startSessionTracker();
setupRequestProcessors(); registerJMX(); setState(State.RUNNING);
notifyAll();
}
}
集群模式
  1. 创建ServerCnxnFactory。

  2. 初始化ServerCnxnFactory。

  3. 创建QuorumPeer实例。

  4. 初始化initialize

    • authServer
    • authLearner
  5. 启动start

    • 设置内部数据库
    • 启动ServerCnxnFactory
    • 启动admin Server
    • 开启选举线程
public class QuorumPeerMain {
public void runFromConfig(QuorumPeerConfig config)
throws IOException, AdminServerException {
//。。。。省略quorumPeer属性赋值
quorumPeer.initialize();
quorumPeer.start();
quorumPeer.join();
}
}

quorumPeer相当于裁判,Quorum是集群模式下特有的对象,是Zookeeper服务器实例(ZooKeeperServer)的托管者,QuorumPeer代表了集群中的一台机器,在运行期间,QuorumPeer会不断检测当前服务器实例的运行状态,同时根据情况发起Leader选举。

public class QuorumPeer{
public void initialize() throws SaslException {
// init quorum auth server & learner
if (isQuorumSaslAuthEnabled()) {
Set<String> authzHosts = new HashSet<String>();
for (QuorumServer qs : getView().values()) {
authzHosts.add(qs.hostname);
}
authServer = new SaslQuorumAuthServer(isQuorumServerSaslAuthRequired(),
quorumServerLoginContext, authzHosts);
authLearner = new SaslQuorumAuthLearner(isQuorumLearnerSaslAuthRequired(),
quorumServicePrincipal, quorumLearnerLoginContext);
} else {
authServer = new NullQuorumAuthServer();
authLearner = new NullQuorumAuthLearner();
}
}
public synchronized void start() {
if (!getView().containsKey(myid)) {
throw new RuntimeException("My id " + myid + " not in the peer list");
}
loadDataBase();
startServerCnxnFactory();
try {
adminServer.start();
} catch (AdminServerException e) {
LOG.warn("Problem starting AdminServer", e);
System.out.println(e);
}
startLeaderElection();
super.start();
}
}

最新文章

  1. NSLOOKUP命令使用
  2. Entity Framework想说爱你不容易,这么多的报错,这么多的限制,该如何解决?
  3. mysql主从复制 转
  4. False Discovery Rate, a intuitive explanation
  5. mysql设置指定ip远程访问连接实例
  6. AutoCAD.NET二次开发:创建自定义菜单(AcCui)
  7. Linux设备驱动编程中的中断与定时器处理
  8. 【poj1087/uva753】A Plug for UNIX(最大流)
  9. Tomcat中Listener的使用范例(转载http://cywhoyi.iteye.com/blog/2075848)
  10. OC基础 可变字典与不可变字典的使用
  11. Android 定义自己的学习(5)它们的定义Progressbar
  12. 使用pip安装报错的处理方法_2
  13. K短路 (A*算法) [Usaco2008 Mar]牛跑步&amp;[Sdoi2010]魔法猪学院
  14. Divisibility by 25 CodeForces - 988E (技巧的暴力)
  15. 那些年我们一起追逐的多线程(Thread、ThreadPool、委托异步调用、Task/TaskFactory、Parallerl、async和await)
  16. js实现按钮开关.单机下拉菜单
  17. 【基于微信小程序的社区电商平台】Alpha迭代心得
  18. Linux网络底层收发探究【转】
  19. 1-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案升级篇(方案总揽)
  20. 20154312 曾林 ExpFinal CTF Writeup

热门文章

  1. gitlab操作笔记
  2. powerDisgner 数据类型对比
  3. MySQL存储引擎MyISAM和InnoDB有哪些区别?
  4. tomcat进行压测时,cpu占用90%
  5. html基础知识(总结自www.runoob.com)
  6. 多线程编程-- part5.1 互斥锁ReentrantLock
  7. 关于获取某月某日最后一天时Calendar的cal.getActualMaximum(Calendar.DAY_OF_MONTH)的吐槽
  8. RaspberryPi交叉编译环境配置-Ubuntu &amp; wiringPi &amp; Qt
  9. DP问题练习1:数字三角最短路径问题
  10. Laying out a webpage is easy with flex