日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

idea zookeeper的使用_学习ZooKeeper源码,就从这篇开始吧

發(fā)布時間:2023/12/4 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 idea zookeeper的使用_学习ZooKeeper源码,就从这篇开始吧 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

【ZooKeeper系列】1.ZooKeeper單機(jī)版、偽集群和集群環(huán)境搭建

【ZooKeeper系列】2.用Java實(shí)現(xiàn)ZooKeeper API的調(diào)用

在系列的前兩篇文章中,介紹了ZooKeeper環(huán)境的搭建(包括單機(jī)版、偽集群和集群),對創(chuàng)建、刪除、修改節(jié)點(diǎn)等場景用命令行的方式進(jìn)行了測試,讓大家對ZooKeeper環(huán)境搭建及常用命令行有初步的認(rèn)識,也為搭建ZooKeeper的開發(fā)環(huán)境、生產(chǎn)環(huán)境起到了拋磚引玉的作用。也介紹了用Java來實(shí)現(xiàn)API的調(diào)用,包括節(jié)點(diǎn)的增、刪、改、查。通過對這兩篇的學(xué)習(xí),讓大家對ZooKeeper的使用有了初步認(rèn)識,也可用于實(shí)現(xiàn)系列后面篇章要介紹的命名服務(wù)、集群管理、分布式鎖、負(fù)載均衡、分布式隊列等。

在前兩篇中,強(qiáng)調(diào)了閱讀英文文檔的重要性,也帶領(lǐng)大家解讀了部分官方文檔,想傳達(dá)出的理念是ZooKeeper沒有想象中的那么難,閱讀官方文檔也沒那么難。后面的篇章中,結(jié)合官方文檔,在實(shí)戰(zhàn)演練和解讀源碼的基礎(chǔ)上加深理解。

上聯(lián):說你行你就行不行也行
下聯(lián):說不行就不行行也不行
橫批:不服不行閱讀源碼就跟這個對聯(lián)一模一樣,就看你選上聯(lián),還是下聯(lián)了!

這一篇開始源碼環(huán)境的搭建。

here we go

很多老鐵留言說很想研讀些github上的開源項目,但代碼clone下來后總出現(xiàn)這樣或那樣奇奇怪怪的問題,很影響學(xué)習(xí)的積極性。學(xué)習(xí)ZooKeeper的源碼尤其如此,很多人clone代碼后,報各種錯,提示少各種包。問了下度娘ZooKeeper源碼環(huán)境,搜出來的文章真的差強(qiáng)人意,有些文章錯的竟然非常離譜。這里我重新搭建了一遍,也會介紹遇到的一些坑。

很多老鐵上來一堆猛操作,從github上下載了ZooKeeper源碼后,按常規(guī)方式導(dǎo)入IDEA,最后發(fā)現(xiàn)少各種包。起初我也是這樣弄的,以為ZooKeeper是用Maven來構(gòu)建的,仔細(xì)去了解了下ZooKeeper的版本歷史,其實(shí)是用的Ant。如今一般用的Maven或Gradle,很少見到Ant的項目了,這里不對Ant多做介紹。

1 Ant環(huán)境搭建

Ant官網(wǎng)地址:https://ant.apache.org/bindownload.cgi

下載解壓后,跟配置jdk一樣配置幾個環(huán)境變量:

//修改為自己本地安裝的目錄
ANT_HOMT=D:\apache-ant-1.10.7?
PATH=%ANT_HOME%/bin
CLASSPATH=%ANT_HOME%/lib

配置好后,測試下Ant是否安裝成功。ant -version,得到如下信息則代表安裝成功:

Apache?Ant(TM)?version?1.10.7?compiled?on?September?1?2019

Ant的安裝跟JDK的安裝和配置非常相似,這里不做過多介紹。

2 下載ZooKeeper源碼

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

猿人谷在寫本篇文章時,releases列表里的最新版本為release-3.5.6,我們以此版本來進(jìn)行源碼環(huán)境的搭建。

3 編譯ZooKeeper源碼

切換到源碼所在目錄,運(yùn)行ant eclipse將項目編譯并轉(zhuǎn)成eclipse的項目結(jié)構(gòu)。

在這里插入圖片描述
這個編譯過程會比較長,差不多等了7分鐘。如果編譯成功,會出現(xiàn)如下結(jié)果:在這里插入圖片描述

4 導(dǎo)入IDEA

上面已經(jīng)將項目編譯并轉(zhuǎn)成eclipse的項目結(jié)構(gòu),按eclipse的形式導(dǎo)入項目。

在這里插入圖片描述在這里插入圖片描述

5 特別說明

將源碼導(dǎo)入IDEA后在org.apache.zookeeper.Version中發(fā)現(xiàn)很多紅色警告,很明顯少了org.apache.zookeeper.version.Info類。

在這里插入圖片描述
查詢源碼得知是用來發(fā)布的時候生成版本用的,我們只是研讀源碼,又不發(fā)布版本所以直接寫死就ok了。在這里插入圖片描述
即新增Info類:package?org.apache.zookeeper.version;

public?interface?Info?{
????int?MAJOR?=?3;
????int?MINOR?=?5;
????int?MICRO?=?6;
????String?QUALIFIER?=?null;
????String?REVISION_HASH?=?"c11b7e26bc554b8523dc929761dd28808913f091";
????String?BUILD_DATE?=?"10/08/2019?20:18?GMT";
}

6 啟動zookeeper

針對單機(jī)版本和集群版本,分別對應(yīng)兩個啟動類:

  • 單機(jī):ZooKeeperServerMain

  • 集群:QuorumPeerMain

這里我們只做單機(jī)版的測試。

在conf目錄里有個zoo_sample.cfg,復(fù)制一份重命名為zoo.cfg

zoo.cfg里的內(nèi)容做點(diǎn)修改(也可以不做修改),方便日志查詢。dataDir和dataLogDir根據(jù)自己的情況設(shè)定。

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

運(yùn)行主類 ?org.apache.zookeeper.server.ZooKeeperServerMain,將zoo.cfg的完整路徑配置在Program arguments。

在這里插入圖片描述
運(yùn)行ZooKeeperServerMain,得到的結(jié)果如下:Connected?to?the?target?VM,?address:?'127.0.0.1:0',?transport:?'socket'
log4j:WARN?No?appenders?could?be?found?for?logger?(org.apache.zookeeper.jmx.ManagedUtil).
log4j:WARN?Please?initialize?the?log4j?system?properly.
log4j:WARN?See?http://logging.apache.org/log4j/1.2/faq.html#noconfig?for?more?info.

告知日志無法輸出,日志文件配置有誤。這里需要指定日志文件log4j.properties。

在這里插入圖片描述
在VM options配置,即指定到conf目錄下的log4j.properties:-Dlog4j.configuration=file:E:/02private/1opensource/zk/zookeeper/conf/log4j.properties

配置后重新運(yùn)行ZooKeeperServerMain,輸出日志如下,

在這里插入圖片描述
可以得知單機(jī)版啟動成功,單機(jī)版服務(wù)端地址為127.0.0.1:2181。

7 啟動客戶端

通過運(yùn)行ZooKeeperServerMain得到的日志,可以得知ZooKeeper服務(wù)端已經(jīng)啟動,服務(wù)的地址為127.0.0.1:2181。啟動客戶端來進(jìn)行連接測試。

客戶端的啟動類為org.apache.zookeeper.ZooKeeperMain,進(jìn)行如下配置:

在這里插入圖片描述
即客戶端連接127.0.0.1:2181,獲取節(jié)點(diǎn)/yuanrengu的信息。

下面帶領(lǐng)大家一起看看客戶端啟動的源碼(org.apache.zookeeper.ZooKeeperMain)。這里要給大家說下我閱讀源碼的習(xí)慣,很多老鐵以為閱讀源碼就是順著代碼看,這樣也沒啥不對,只是很多開源項目代碼量驚人,這么個干看法,容易注意力分散也容易看花眼。我一般是基于某個功能點(diǎn),從入口開始debug跑一遍,弄清這個功能的“代碼線”,就像跑馬圈塊地兒一樣,弄清楚功能有關(guān)的代碼,了解參數(shù)傳遞的過程,這樣看代碼時就更有針對性,也能排除很多干擾代碼。

7.1 main

main里就兩行代碼,通過debug得知args里包含的信息就是上面我們配置在Program arguments里的信息:

在這里插入圖片描述

7.1.1 ZooKeeperMain

????public?ZooKeeperMain(String?args[])?throws?IOException,?InterruptedException?{
????????//?用于解析參數(shù)里的命令行的
????????cl.parseOptions(args);
????????System.out.println("Connecting?to?"?+?cl.getOption("server"));
????????//?用于連接ZooKeeper服務(wù)端
????????connectToZK(cl.getOption("server"));
????}

通過下圖可以看出,解析參數(shù)后,就嘗試連接127.0.0.1:2181,即ZooKeeper服務(wù)端。cl.getOption("server")得到的就是127.0.0.1:2181。

在這里插入圖片描述

7.1.2 parseOptions

在這里插入圖片描述可以很清楚的得知解析args的過程,主要從"-server","-timeout","-r","-"這幾個維度來進(jìn)行解析。

7.1.3 connectToZK

????protected?void?connectToZK(String?newHost)?throws?InterruptedException,?IOException?{
????????//?用于判斷現(xiàn)在ZooKeeper連接是否還有效
????????//?zk.getState().isAlive()?注意這個會話是否有效的判斷,客戶端與?Zookeeper連接斷開不一定會話失效
????????if?(zk?!=?null?&&?zk.getState().isAlive())?{
????????????zk.close();
????????}

????????//?此時newHost為127.0.0.1:2181
????????host?=?newHost;
????????//?判斷是否為只讀模式,關(guān)于只讀模式的概念在前一篇文章中有介紹
????????boolean?readOnly?=?cl.getOption("readonly")?!=?null;
????????//?用于判斷是否建立安全連接
????????if?(cl.getOption("secure")?!=?null)?{
????????????System.setProperty(ZKClientConfig.SECURE_CLIENT,?"true");
????????????System.out.println("Secure?connection?is?enabled");
????????}
????????zk?=?new?ZooKeeperAdmin(host,?Integer.parseInt(cl.getOption("timeout")),?new?MyWatcher(),?readOnly);
????}

ZKClientConfig.SECURE_CLIENT已經(jīng)被標(biāo)注為deprecation了:

????/**
?????*?Setting?this?to?"true"?will?enable?encrypted?client-server?communication.
?????*/
????@SuppressWarnings("deprecation")
????public?static?final?String?SECURE_CLIENT?=?ZooKeeper.SECURE_CLIENT;

debug查看關(guān)鍵點(diǎn)處的信息,可以得知這是建立一個ZooKeeper連接的過程(【ZooKeeper系列】2.用Java實(shí)現(xiàn)ZooKeeper API的調(diào)用)

下圖看看幾處關(guān)鍵信息:

在這里插入圖片描述
Integer.parseInt(cl.getOption("timeout"))為30000。

至此完成了ZooKeeperMain main = new ZooKeeperMain(args);的整個過程。簡短點(diǎn)說就是:

  • 解析Program arguments里的參數(shù)

  • 連接ZooKeeper服務(wù)端

  • 7.2 main.run()

    敲黑板,重頭戲來了哦!

    一起來看下run()的代碼:

    ????void?run()?throws?CliException,?IOException,?InterruptedException?{
    ????????//?cl.getCommand()得到的是?“get”,就是上文傳進(jìn)來的
    ????????if?(cl.getCommand()?==?null)?{
    ????????????System.out.println("Welcome?to?ZooKeeper!");

    ????????????boolean?jlinemissing?=?false;
    ????????????//?only?use?jline?if?it's?in?the?classpath
    ????????????try?{
    ????????????????Class>?consoleC?=?Class.forName("jline.console.ConsoleReader");
    ????????????????Class>?completorC?=
    ????????????????????Class.forName("org.apache.zookeeper.JLineZNodeCompleter");

    ????????????????System.out.println("JLine?support?is?enabled");

    ????????????????Object?console?=
    ????????????????????consoleC.getConstructor().newInstance();

    ????????????????Object?completor?=
    ????????????????????completorC.getConstructor(ZooKeeper.class).newInstance(zk);
    ????????????????Method?addCompletor?=?consoleC.getMethod("addCompleter",
    ????????????????????????Class.forName("jline.console.completer.Completer"));
    ????????????????addCompletor.invoke(console,?completor);

    ????????????????String?line;
    ????????????????Method?readLine?=?consoleC.getMethod("readLine",?String.class);
    ????????????????while?((line?=?(String)readLine.invoke(console,?getPrompt()))?!=?null)?{
    ????????????????????executeLine(line);
    ????????????????}
    ????????????}?catch?(ClassNotFoundException?e)?{
    ????????????????LOG.debug("Unable?to?start?jline",?e);
    ????????????????jlinemissing?=?true;
    ????????????}?catch?(NoSuchMethodException?e)?{
    ????????????????LOG.debug("Unable?to?start?jline",?e);
    ????????????????jlinemissing?=?true;
    ????????????}?catch?(InvocationTargetException?e)?{
    ????????????????LOG.debug("Unable?to?start?jline",?e);
    ????????????????jlinemissing?=?true;
    ????????????}?catch?(IllegalAccessException?e)?{
    ????????????????LOG.debug("Unable?to?start?jline",?e);
    ????????????????jlinemissing?=?true;
    ????????????}?catch?(InstantiationException?e)?{
    ????????????????LOG.debug("Unable?to?start?jline",?e);
    ????????????????jlinemissing?=?true;
    ????????????}

    ????????????if?(jlinemissing)?{
    ????????????????System.out.println("JLine?support?is?disabled");
    ????????????????BufferedReader?br?=
    ????????????????????new?BufferedReader(new?InputStreamReader(System.in));

    ????????????????String?line;
    ????????????????while?((line?=?br.readLine())?!=?null)?{
    ????????????????????executeLine(line);
    ????????????????}
    ????????????}
    ????????}?else?{
    ????????????//?處理傳進(jìn)來的參數(shù)
    ????????????processCmd(cl);
    ????????}
    ????????System.exit(exitCode);
    ????}

    通過下圖可以看出processCmd(cl);里cl包含的信息:

    在這里插入圖片描述
    debug到processCmd(MyCommandOptions co) 就到了決戰(zhàn)時刻。里面的processZKCmd(MyCommandOptions co)就是核心了,代碼太長,只說下processZKCmd里的重點(diǎn)代碼,獲取節(jié)點(diǎn)/yuanrengu的信息:在這里插入圖片描述
    因為我之前沒有創(chuàng)建過/yuanrengu節(jié)點(diǎn),會拋異常org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = NoNode for /yuanrengu , 如下圖所示:在這里插入圖片描述
    經(jīng)過上面的步驟后exitCode為1,執(zhí)行System.exit(exitCode);退出。

    至此帶領(lǐng)大家dubug了一遍org.apache.zookeeper.ZooKeeperMain,上面我說過,閱讀源碼干看效果很小,只有debug才能有助于梳理流程和思路,也能清楚參數(shù)傳遞的過程發(fā)生了什么變化。

    溫馨提示

    上面我們介紹了源碼環(huán)境的搭建過程,運(yùn)行運(yùn)行主類 ?org.apache.zookeeper.server.ZooKeeperServerMain 啟動ZooKeeper服務(wù)端,運(yùn)行org.apache.zookeeper.ZooKeeperMain連接服務(wù)端。

    閱讀源碼最好能動起來(debug)讀,這樣代碼才是活的,干看的話代碼如死水一樣,容易讓人索然無味!

    每個人操作的方式不一樣,有可能遇到的問題也不一樣,搭建過程中遇到什么問題,大家可以在評論區(qū)留言。

    如果希望更多ZooKeeper的文章,務(wù)必留言告知

    總結(jié)

    以上是生活随笔為你收集整理的idea zookeeper的使用_学习ZooKeeper源码,就从这篇开始吧的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。