zookeeper启动入口
最近正在研究zookeeper,一些心得记录一下,如有错误,还请大神指正。
zookeeper下载地址:http://zookeeper.apache.org/releases.html,百度一下就能找到,不过还是在这里列一下。
我认为学习一个东西,首先要理出一个头绪,否则感觉无从下手,这里我从启动开始研究,即从zkSever.sh入手。
if [ "x$JMXDISABLE" = "x" ]
then
echo "JMX enabled by default" >&2
# for some reason these two options are necessary on jdk6 on Ubuntu
# accord to the docs they are not necessary, but otw jconsole cannot
# do a local attach
ZOOMAIN="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=$JMXLOCALONLY org.apache.zookeeper.server.quorum.QuorumPeerMain"
else
echo "JMX disabled by user request" >&2
ZOOMAIN="org.apache.zookeeper.server.quorum.QuorumPeerMain"
fi
从zkSever.sh可以看出,启动入口在QuorumPeerMain中,源码如下:
// 入口函数
public static void main(String[] args)
{
QuorumPeerMain main = new QuorumPeerMain();
//...1、启动初始化
main.initializeAndRun(args);
// ...
} protected void initializeAndRun(String[] args)
throws QuorumPeerConfig.ConfigException, IOException
{
// 2、加载配置文件
QuorumPeerConfig config = new QuorumPeerConfig();
if (args.length == 1) {
// 解析配置文件
config.parse(args[0]);
} if ((args.length == 1) && (config.servers.size() > 0)) {
// 配置文件的信息加载至QuorumPeer
runFromConfig(config);
} else {
LOG.warn("Either no config or no quorum defined in config, running in standalone mode"); ZooKeeperServerMain.main(args);
}
} public void runFromConfig(QuorumPeerConfig config) throws IOException {
try {
ManagedUtil.registerLog4jMBeans();
} catch (JMException e) {
LOG.warn("Unable to register log4j JMX control", e);
} LOG.info("Starting quorum peer");
try {
NIOServerCnxn.Factory cnxnFactory = new NIOServerCnxn.Factory(config.getClientPortAddress(), config.getMaxClientCnxns()); // 3、启动QuorumPeer
this.quorumPeer = new QuorumPeer();
this.quorumPeer.setClientPortAddress(config.getClientPortAddress());
//...加载各种配置信息 this.quorumPeer.start();
this.quorumPeer.join();
}
catch (InterruptedException e) {
LOG.warn("Quorum Peer interrupted", e);
}
}
可以看出,配置文件的解析由QuorumPeerConfig 类完成,其部分源码如下:
public void parse(String path)
throws QuorumPeerConfig.ConfigException
{
File configFile = new File(path); LOG.info("Reading configuration from: " + configFile);
try
{
if (!configFile.exists()) {
throw new IllegalArgumentException(configFile.toString() + " file is missing");
}
// 将配置信息加载如property文件
Properties cfg = new Properties();
FileInputStream in = new FileInputStream(configFile);
try {
cfg.load(in);
} finally {
in.close();
} parseProperties(cfg);
} catch (IOException e) {
throw new ConfigException("Error processing " + path, e);
} catch (IllegalArgumentException e) {
throw new ConfigException("Error processing " + path, e);
}
} public void parseProperties(Properties zkProp)
throws IOException, QuorumPeerConfig.ConfigException
{
int clientPort = 0;
String clientPortAddress = null;
// 循环解析配置文件
for (Map.Entry entry : zkProp.entrySet()) {
String key = entry.getKey().toString().trim();
String value = entry.getValue().toString().trim();
if (key.equals("dataDir")) {
this.dataDir = value;
} else if (key.equals("dataLogDir")) {
this.dataLogDir = value;
} else if (key.equals("clientPort")) {
// 客户端连接的端口号
clientPort = Integer.parseInt(value);
} else if (key.equals("clientPortAddress")) {
clientPortAddress = value.trim();
} else if (key.equals("tickTime")) {
// 心跳时间
this.tickTime = Integer.parseInt(value);
} else if (key.equals("maxClientCnxns")) {
this.maxClientCnxns = Integer.parseInt(value);
} else if (key.equals("minSessionTimeout")) {
this.minSessionTimeout = Integer.parseInt(value);
} else if (key.equals("maxSessionTimeout")) {
this.maxSessionTimeout = Integer.parseInt(value);
} else if (key.equals("initLimit")) {
this.initLimit = Integer.parseInt(value);
} else if (key.equals("syncLimit")) {
this.syncLimit = Integer.parseInt(value);
} else if (key.equals("electionAlg")) {
// 选举算法的类型,默认算法为FastLeaderElection
this.electionAlg = Integer.parseInt(value);
} else if (key.equals("peerType")) {
if (value.toLowerCase().equals("observer"))
this.peerType = QuorumPeer.LearnerType.OBSERVER;
else if (value.toLowerCase().equals("participant")) {
this.peerType = QuorumPeer.LearnerType.PARTICIPANT;
}
else
throw new ConfigException("Unrecognised peertype: " + value);
}
//...
回到QuorumPeerMain类的runFromConfig方法。此方法中,会将配置信息加载至QuorumPeer,并调用其start方法:
public synchronized void start()
{
try {
this.zkDb.loadDataBase();
} catch (IOException ie) {
LOG.fatal("Unable to load database on disk", ie);
throw new RuntimeException("Unable to run quorum server ", ie);
}
this.cnxnFactory.start();
startLeaderElection();
super.start();
}
在start方法中,会现价在硬盘中的数据,
this.zkDb.loadDataBase();即ZKDatabase中
public long loadDataBase()
throws IOException
{
FileTxnSnapLog.PlayBackListener listener = new FileTxnSnapLog.PlayBackListener() {
public void onTxnLoaded(TxnHeader hdr, Record txn) {
Request r = new Request(null, 0L, hdr.getCxid(), hdr.getType(), null, null); r.txn = txn;
r.hdr = hdr;
r.zxid = hdr.getZxid();
ZKDatabase.this.addCommittedProposal(r);
}
};
long zxid = this.snapLog.restore(this.dataTree, this.sessionsWithTimeouts, listener);
this.initialized = true;
return zxid;
}
然后开确定选类型,startLeaderElection
public synchronized void startLeaderElection() {
this.currentVote = new Vote(this.myid, getLastLoggedZxid());
for (QuorumServer p : getView().values()) {
if (p.id == this.myid) {
this.myQuorumAddr = p.addr;
break;
}
}
if (this.myQuorumAddr == null) {
throw new RuntimeException("My id " + this.myid + " not in the peer list");
}
if (this.electionType == 0) {
try {
this.udpSocket = new DatagramSocket(this.myQuorumAddr.getPort());
this.responder = new ResponderThread();
this.responder.start();
} catch (SocketException e) {
throw new RuntimeException(e);
}
}
this.electionAlg = createElectionAlgorithm(this.electionType);//加载选举类型
}
然后启动run方法
zookeeper启动入口的更多相关文章
- Zookeeper启动过程
在上一篇,我们了解了zookeeper最基本的配置,也从中了解一些配置的作用,那么这篇文章中,我们将介绍Zookeeper的启动过程,我们在了解启动过程的时候还要回过头看看上一篇中各个配置参数在启动时 ...
- zookeeper源码学习一——zookeeper启动
最近正在研究zookeeper,一些心得记录一下,如有错误,还请大神指正. zookeeper下载地址:http://zookeeper.apache.org/releases.html,百度一下就能 ...
- zookeeper启动流程简单梳理
等着測试童鞋完工,顺便里了下zookeeper的启动流程 zk3.4.6 启动脚本里面 nohup "$JAVA" "-Dzookeeper.log.dir=${ZOO_ ...
- 服务端相关知识学习(四)之Zookeeper启动过程
在上一篇,我们了解了zookeeper最基本的配置,也从中了解一些配置的作用,那么这篇文章中,我们将介绍Zookeeper的启动过程,我们在了解启动过程的时候还要回过头看看上一篇中各个配置参数在启动时 ...
- zookeeper启动报错(数据目录权限不对)
zookeeper启动报错日志: 2016-11-16 11:19:43,880 [myid:3] - INFO [WorkerReceiver[myid=3]:FastLeaderElection@ ...
- python爬虫主要就是五个模块:爬虫启动入口模块,URL管理器存放已经爬虫的URL和待爬虫URL列表,html下载器,html解析器,html输出器 同时可以掌握到urllib2的使用、bs4(BeautifulSoup)页面解析器、re正则表达式、urlparse、python基础知识回顾(set集合操作)等相关内容。
本次python爬虫百步百科,里面详细分析了爬虫的步骤,对每一步代码都有详细的注释说明,可通过本案例掌握python爬虫的特点: 1.爬虫调度入口(crawler_main.py) # coding: ...
- zookeeper启动异常
zookeeper启动报异常 java.io.EOFException at java.io.DataInputStream.readInt(DataInputStream.java:392) 遇到 ...
- Zookeeper启动时报8080端口被占用
zookeeper启动时报8080 端口被占用,导致启动失败.特别是服务器上部署了tomcat服务时需要注意. 通过查看zookeeper的官方文档,发现有3种解决途径: (1)删除jetty. (2 ...
- SpringBoot(二):设置springboot同一接口程序启动入口
根据上一篇文章中搭建了一个springboot简单工程,在该工程中编写HelloWordController.java接口类,并在该类中写了一个main函数,做为该类的接口服务启动入口.此时如果新增多 ...
随机推荐
- PHP文件系统处理(二)
1.文件的打开和关闭(读文件中的内容,向文件中写内容) 读取文件中的内容 file_get_contents() //php5以上 < ...
- UVA11624(bfs)
题意:给一张图,有火源,有障碍物,剩下的是道路,火源在下一分钟能够让上下左右四个方向的道路也着火,告诉人的位置,问最短时间能逃出去的时间是多少: 思路:一个bfs用来求出所有的火源能蔓延到的地方,另一 ...
- PHP访问REST API上传文件的解决方案
最近写的一个小功能需要通过rest方式上传文件,因此就在网上找了一些解决方案.接下来说明以下我采用的解决方案:我是利用curl来实现的,其中CURLOPT_POST的值为TRUE代表的是请求类型为PO ...
- magento安装以及搬家的注意事项
如果你的空间可以用ssh的话,你可以在官网的wiki Moving Magento To Another Server 中看到较为详细的搬家过程. 无论你的服务器是linux系统还是windows系统 ...
- 搭建 hexo,在执行 hexo deploy 后,出现 error deployer not found:github 的错误
hexo 更新到3.0之后,deploy的type 的github需要改成git 改了之后执行npm install hexo-deployer-git --save 然后再部署试试 官网说明: ht ...
- CGI实现页面的动态生成
传统的Web应用开发局限于有限的静态页面(HTML静态页面),不利于系统的扩展,不能提供及时信息,而且修改维护麻烦,所以建立一个动态Web应用程序尤为重要.一方面根据访问者的不同请求返回不同的访问信息 ...
- SqlServer 杂记 不断补充中
1.OPTION (MAXRECURSION 25) :最大允许递归的次数.默认最大CTE递归只有100次,而你要求插入10年的数据,需要递归3000多次,所以要使用option (MAXRECURS ...
- nginx+tomcat集群配置(2)---静态和动态资源的分离
前言: 在web性能优化的领域, 经常能听到一个词, 就是静态/动态资源分离. 那静态/动态资源分离究竟是什么呢? 本文不讲文件系统服务, 云存储, 也不讲基于CDN的优化. 就简单讲讲基于nginx ...
- ZSDR100 跑原材料MRP
*&---------------------------------------------------------------------**& Report ZSDR100*&a ...
- tyvj1013 - 找啊找啊找GF ——二维背包变种
题目链接:https://www.tyvj.cn/Problem_Show.aspx?id=1013 好吧,这题没节操=_= 状态f[u,v,i]表示:消费u的人民币和v的人品同时泡到i个mm所需要的 ...