理想下载站 手游攻略 软件教程 学习ZooKeeper源码,从这篇文章开始

学习ZooKeeper源码,从这篇文章开始

时间:2024-10-20 23:29:31 来源: 浏览:55

大家好,关于学习ZooKeeper源码,从这篇文章开始很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!

在前两篇文章中,我强调了阅读英文文档的重要性,也带领大家解读了一些官方文档。我想传达的想法是ZooKeeper并没有想象中的那么难,阅读官方文档也没有那么难。在后面的章节中,我们将结合官方文档,在实际练习和源码解读的基础上加深理解。

第一联:你说能行,那你就可以行,也可以不行。

第二行:如果不起作用,那就不起作用,不起作用,而且不起作用。

横批:不接受就做不到。

读源码和这副对联一模一样,就看你选择上联还是下联了!

本文开始源码环境的搭建,开始吧!

很多老手留言表示想研究Github上的一些开源项目,但是代码clone后总是出现这样或那样的奇怪问题,极大影响了学习的积极性。在学习ZooKeeper的源码时尤其如此。许多人在克隆代码后报告各种错误和丢失的包。问了度娘的ZooKeeper源码环境后,发现的文章实在是差强人意,有的文章错误很大。这里我重新搭建了一下,也会介绍一下我遇到的一些坑。

许多退伍。。付出了很多努力。从github下载了ZooKeeper源码后,按照通常的方式导入IDEA,最后发现缺少各种包。起初,我也做了同样的事情,认为ZooKeeper是使用Maven构建的。仔细研究了ZooKeeper的版本历史,发现其实用的是Ant。现在普遍使用的是Maven或者Gradle,Ant项目很少见到。这里我就不详细介绍Ant了。

1 蚂蚁环境搭建

Ant官网地址:https://ant.apache.org/bindownload.cgi

下载解压后,像配置jdk一样配置几个环境变量:

//修改为自己本地安装的目录ANT_HOMT=D:\apache-ant-1.10.7PATH=%ANT_HOME%/binCLASSPATH=%ANT_HOME%/lib

配置完成后,测试Ant是否安装成功。 ant -version,如果得到以下信息,则说明安装成功:

ApacheAnt(TM)版本1.10.7于2019年9月编译

Ant的安装与JDK的安装和配置非常相似,这里不再赘述。

2 下载ZooKeeper源码

源码地址:https://github.com/apache/zookeeper

当猿人谷写这篇文章时,发布列表中的最新版本是release-3.5.6。我们使用这个版本来搭建源码环境。

3 编译ZooKeeper源码

切换到源代码所在目录,运行ant eclipse 编译项目并转换为eclipse项目结构。

这个编译过程会花费很长的时间,差不多7分钟。如果编译成功,会出现如下结果:

4 导入IDEA

项目已经编译并转换为上面的eclipse项目结构,并且项目已经以eclipse的形式导入。

5特别说明

将源码导入IDEA后,发现org.apache.zookeeper.Version中有很多红色警告。很明显,org.apache.zookeeper.version.Info 类丢失了。

查询源码后发现是发布时用来生成版本的。我们只研究源码,不发布版本,只能写死了。

即添加Info类:

packageorg.apache.zookeeper.version;publicinterfaceInfo{intMAJOR=3;intMINOR=5;intMICRO=6;StringQUALIFIER=null;StringREVISION_HASH='c11b7e26bc554b8523dc929761dd28808913f091';StringBUILD_DATE='10/08/2019203 336018GMT' ;}

6 启动动物园管理员

对于单机版和集群版来说,有两个启动类:

独立:ZooKeeperServerMain

集群:QuorumPeerMain

这里我们只测试单机版。

对zoo.cfg中的内容进行一些修改(或不修改),以方便日志查询。 dataDir和dataLogDir根据自己的情况设置。

dataDir=E:\\02private\\1opensource\\zk\\zookeeper\\dataDir dataLogDir=E:\\02private\\1opensource\\zk\\zookeeper\\dataLogDir

运行主类org.apache.zookeeper.server.ZooKeeperServerMain,并在Program arguments中配置zoo.cfg的完整路径。

运行ZooKeeperServerMain,结果如下:

连接到目标VM,地址:'127.0.0.1:0',传输:'套接字'log4j:WARN无法找到记录器(org.apache.zookeeper.jmx.ManagedUtil)的appender。log4j:WARN请正确初始化log4j系统。log4j:WARNSee3335 8logging。 apache.org/log4j/1.2/faq.html#noconfigformoreinfo。

提示日志无法输出,日志文件配置不正确。这里需要指定日志文件log4j.properties。

在VM选项配置中,在conf目录中指定log4j.properties:

-Dlog4j.configuration=file:E:/02private/1opensource/zk/zookeeper/conf/log4j.properties

配置完成后,重新运行ZooKeeperServerMain。输出日志如下:

可以知道单机版启动成功,单机版服务器地址为127.0.0.1:2181。

7 启动客户端

从运行ZooKeeperServerMain得到的日志中,我们可以知道ZooKeeper服务器已经启动,服务地址为127.0.0.1:2181。启动客户端测试连接。

客户端的启动类为org.apache.zookeeper.ZooKeeperMain,需要进行如下配置:

即客户端连接127.0.0.1:2181获取node/yuanrengu的信息。

我们看一下客户端启动的源码(org.apache.zookeeper.ZooKeeperMain)。这里我想向大家介绍一下我阅读源码的习惯。很多人认为阅读源代码就是遵循代码。这并没有什么问题。只是很多开源项目的代码量惊人。这种思维方式很容易分散注意力和阅读。令人眼花缭乱。我通常会根据某个函数点从。。点开始调试运行,以找出该函数的“代码行”。就像跑赛马一样,要弄清楚函数相关的代码,了解参数传递的过程。这样看代码会更有针对性,可以排除很多干扰代码。

7.1 主要

main 中只有两行代码。通过调试,我们知道args中包含的信息就是我们上面Programarguments中配置的信息:

7.1.1 ZooKeeper主程序

publicZooKeeperMain(Stringargs[])throwsIOException,InterruptedException{//cl.parseOptions(args)用于解析参数中的命令行;System.out.println('Connectingto'+cl.getOption('server'));//使用连接到ZooKeeper 服务器connectToZK(cl.getOption('server'));}

从下图可以看出,解析完参数后,它尝试连接127.0.0.1:2181,即ZooKeeper服务器。 cl.getOption('server') 获取127.0.0.1:2181。

7.1.2 解析选项

可以清楚地理解,解析args的过程主要是从'-server'、'-timeout'、'-r'、'-'维度来分析。

7.1.3 连接到ZK

protectedvoidconnectToZK(StringnewHost) throwsInterruptedException,IOException{//用于判断ZooKeeper连接是否仍然有效//zk.getState().isAlive() 注意本次会话是否有效的判断。客户端与Zookeeper断开并不一定会导致会话失效if (zk!=nullzk.getState().isAlive()){zk.close();}//此时newHost为127.0.0.1:2181host=newHost; //判断是否是只读模式,关于只读模式的概念在上一篇文章中介绍过boolean readOnly=cl.getOption('readonly')!=null;//用于判断是否建立安全连接if(cl.getOption('secure')!=null){System.setProperty( ZKClientConfig.SECURE_CLIENT,'true');System.out.println('Secureconnectionisenabled');}zk=newZooKeeperAdmin(host,Integer.parseInt( cl.getOption('超时')),newMyWatcher(),readOnly);}

ZKClientConfig.SECURE_CLIENT 已被标记为弃用:

/***将此设置为“true”将启用加密的客户端-服务器通信。*/@SuppressWarnings('deprecation')publicstaticfinalStringSECURE_CLIENT=ZooKeeper.SECURE_CLIENT;

调试查看关键点信息,可以知道这就是建立ZooKeeper连接的过程(【ZooKeeper系列】2.使用Java实现ZooKeeper API调用,本文详细介绍了建立ZooKeeper连接的过程)

看看下面的一些关键信息:

Integer.parseInt(cl.getOption('timeout')) 是30000。

这样就完成了ZooKeeperMain main=new ZooKeeperMain(args);的整个过程。简单来说:

解析程序参数中的参数

连接到ZooKeeper 服务器

连接ZooKeeper的过程也很精彩:

将进一步调用以下方法:

还会多一步createDefaultHostProvider(connectString),其中connectString为127.0.0.1:2181。

继续手淫:

还有一个ZKClientConfig 类型的附加参数,默认为null。在3.5.2版本中添加了ZKClientConfig,以实现不同ZooKeeper实例中更灵活的属性配置。

ZooKeeper连接过程是不是越来越精彩了?然后我们继续自慰:

createConnection的方法也是重点,标记为VisibleForTesting:

//@VisibleForTestingprotectedClientCnxncreateConnection(StringchrootPath,HostProviderhostProvider,intsessionTimeout,ZooKeeperzooKeeper,ClientWatchManagerwatcher,ClientCnxnSocketclientCnxnSocket,booleancanBeReadOnly) throwsIOException{returnnewClientCnxn(chrootPath,hostProvider,会话超时,this,watchManager,clientCnxnSocket,canBeReadOnly);}

createConnection方法中核心代码如下:

有两行代码特别有趣。可以通过上图观察参数值的变化:

//链接超时connectTimeout=sessionTimeout/hostProvider.size(); //读取响应超时readTimeout=sessionTimeout*2/3;

随着cnxn.start();的执行,ZooKeeper连接完成:

7.2 main.run()

敲黑板,重头戏来了!

我们看一下run() 代码:

voidrun() throwsCliException,IOException,InterruptedException{//cl.getCommand()得到“get”,就是上面传入的那个if(cl.getCommand()==null){System.out.println('WelcometoZooKeeper! ' );booleanjlinemissing=false;//只使用jlineifit'sintheclasspathtry{Class?consoleC=Class.forName('jline.console.ConsoleReader');Class?completorC=Class.forName('org.apache.zookeeper.JLineZNodeCompleter');System . out.println('JLinesupportisenabled');Objectconsole=consoleC.getConstructor().newInstance();Objectcompletor=completorC.getConstructor(ZooKeeper.class).newInstance(zk);MethodaddCompletor=consoleC.getMethod('addCompleter',Class.forName ('jline.console.completer.Completer'));addCompletor.invoke(console,completor);Stringline;MethodreadLine=consoleC.getMethod('readLine',String.class);while((line=(String)readLine.invoke (console,getPrompt()))!=null){executeLine(line);}}catch(ClassNotFoundExceptione){LOG.debug('Unabletostartjline',e);jlinemissing=true;}catch(NoSuchMethodExceptione){LOG.debug ( 'Unabletostartjline',e);jlinemissing=true;}catch(InitationTargetExceptione){LOG.debug('Unabletostartjline',e);jlinemissing=true;}catch(IllegalAccessExceptione){LOG.debug('Unabletostartjline',e); jlinemissing=true;}catch(InstantiationExceptione){LOG.debug('Unabletostartjline',e);jlinemissing=true;}if(jlinemissing){System.out.println('JLinesupportisdisabled');BufferedReaderbr=newBufferedReader(newInputStreamReader(System. in));Stringline;while((line=br.readLine())!=null){executeLine(line);}}}else{//处理传入参数processCmd(cl);}System.exit(exitCode ) ;}

下图展示了processCmd(cl);中cl包含的信息:

调试到processCmd(MyCommandOptions co),就到了决战的时候了。里面的processZKCmd(MyCommandOptions co)是核心。代码太长。我只讲processZKCmd中获取node/yuanrengu信息的关键代码:

因为之前没有创建过/yuanrengu节点,所以会抛出异常org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode=NoNode for /yuanrengu,如下图:

经过上述步骤后,exitCode为1,执行System.exit(exitCode);退出。

至此,我就带领大家调试了org.apache.zookeeper.ZooKeeperMain。上面说了,读源码收效甚微。只有调试才能帮助理清流程和思路,也能明确参数传递过程发生了哪些变化。

温馨提示

上面我们介绍了源码环境搭建的过程,运行主类org.apache.zookeeper.server.ZooKeeperServerMain启动ZooKeeper服务器,并运行org.apache.zookeeper.ZooKeeperMain连接服务器。

在分析与ZooKeeper的连接过程中,出现了HostProvider、ZKClientConfig、ClientCnxn等。这些都是非常重要的概念。后面的系列文章中会有一篇文章从源码层面深入分析与ZooKeeper服务器的连接,重点解释为什么需要这样做。事物,以及它们可以发挥哪些奇妙的用途。

最好带着debug来读源码,这样代码才是活的。如果干巴巴地看,代码就会像一潭死水一样,很容易让人厌烦!

用户评论

淡写薰衣草的香

看了一下这篇文章,感觉写得挺不错的!ZooKeeper一直想深入了解一下,正好这篇文章可以作为入门指南,把一些关键点都总结出来了。终于不用在那堆源码里摸索了!

    有20位网友表示赞同!

颓废人士

想学ZooKeeper源码?真的不是一个容易的事情。作者提到的一些注意点我已经感受到难度很大,但是看到这么一篇入门指南还是挺开心的,希望可以让我少走一些弯路。

    有14位网友表示赞同!

墨城烟柳

其实对于刚入门的人来说,ZooKeeper的架构和机制确实比较复杂。这篇文章把重点提炼出来,确实能帮助我们快速了解基本概念,准备开始阅读源码学习了!

    有7位网友表示赞同!

怪咖

我一直觉得学开源代码最重要的一点是能够理解作者的设计思路。这篇博文就提到了ZooKeeper的一些设计思想,这对我们进行深入学习非常有帮助!

    有19位网友表示赞同!

陌颜

这篇博客虽然介绍的重点不多,但我觉得对于刚刚入门ZooKeeper的人来说已经足够了。接下来我会慢慢阅读代码,将这些概念进一步加深理解!

    有7位网友表示赞同!

还未走i

感觉这篇文章把 ZooKeeper 最重要的点都提炼出来了,比如它的分布式特性、状态机设计等等。想学习源代码的同学可以先温习一下这篇博客哦!

    有8位网友表示赞同!

抚笙

ZooKeeper 源码确实比较复杂,如果一开始就一头扎进去可能会很难理解。这篇博文介绍了一些入门知识和建议,能帮我们更好地规划学习路线,避免盲目学习。

    有5位网友表示赞同!

黑夜漫长

我觉得这篇文章的总结部分做得不错,把 ZooKeeper 的重点集中在一起方便记忆和复习。学习源码可不是一蹴而就的事情,需要反复阅读和理解!

    有20位网友表示赞同!

微信名字

有点儿失望。这篇博客虽然介绍了 ZooKeeper 的一些基本概念,但对源码本身并没有太多具体解释。想要深入了解代码还需要去看其他资料。

    有7位网友表示赞同!

搞搞嗎妹妹

ZooKeeper 作为分布式系统里的重要组件,确实需要好好学习一下它的源码。不过这篇文章提供的材料感觉不够全面,希望作者可以补充更多实践经验分享!

    有8位网友表示赞同!

我家的爱豆是怪比i

我建议想学ZooKeeper源代码的同学先学习一些基本的Java语言知识和并发编程概念。这篇博文并没有太多相关的讲解。

    有12位网友表示赞同!

殃樾晨

对于已经对 ZooKeeper 有一定的了解的人来说,这篇文章的内容可能比较容易懂。但对于完全入门的新手来说,学习难度可能会有所挑战。

    有11位网友表示赞同!

情字何解ヘ

我感觉这篇文章的结构有点凌乱,有些关键信息被分散在不同段落中。希望能按照更清晰逻辑来组织内容,方便读者更好地理解。

    有13位网友表示赞同!

别悲哀

我觉得这篇文章写得还可以,至少让我对ZooKeeper 有一些基本了解了。不过我更希望作者能提供一些实际案例和源码解析的例子,这样才能更加深入地理解ZooKeeper 的工作机制。

    有8位网友表示赞同!

裸睡の鱼

学习 ZooKeeper 源码的确需要时间和耐心,这篇博文虽然有一定的参考价值,但它仅仅是一个入门指南,不能概括源码的所有内容。 需要根据自己的实际情况选择适合的学习资料。

    有13位网友表示赞同!

空巷

ZooKeeper确实是一套非常强大的分布式协调框架,我一直在想学习它的源码来深入了解它的工作原理。这次看到这篇文章感觉很激动,希望能够坚持下去,最终掌握它的知识!

    有7位网友表示赞同!

独角戏°

我认为文章写的很清晰易懂,适合想要入門ZooKeeper的人阅读。作者提到的重点让我对ZooKeeper的一个初步的理解了,接下来我会继续去看更多关于ZooKeeper的内容。

    有15位网友表示赞同!

歆久

学习 ZooKeeper 源码是一项挑战,但是随着我对互联网分布式系统的了解不断加深,我相信 ZooKeeper 对我的学习之路非常重要。这篇博文给我提供了很好的启发和方向。

    有17位网友表示赞同!

标题:学习ZooKeeper源码,从这篇文章开始
链接:https://www.ltthb.com/news/rj/131217.html
版权:文章转载自网络,如有侵权,请联系删除!
资讯推荐
更多
怎么不让快递放菜鸟驿站

菜鸟裹裹怎么禁止放快递?经常网购的小伙伴都知道,如果附近有菜鸟驿站,那么驿站的快递员会默认选择放在驿站中,并

2024-10-20
菜鸟驿站怎么送货上门

菜鸟裹裹怎么送货上门?有过菜鸟驿站拿快递的小伙伴都知道,很多菜鸟驿站在派送快递时,默认是放在菜鸟驿站,需要我

2024-10-20
蚂蚁庄园2021年3月4日最新答案

蚂蚁庄园3月4日答案最新是什么?在支付宝蚂蚁庄园每日一题中,每天都会有多个问题等着大家来回答,回答正确后即可

2024-10-20
一起学APP海星商城在哪里

一起学APP海星商城在哪里?在最近,很多用户都在问一起学APP的海星商店在哪里,一起学APP海星商城在哪里,怎么进入

2024-10-20