91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何調試大型開源項目ZooKeeper

發布時間:2021-10-14 15:40:53 來源:億速云 閱讀:125 作者:iii 欄目:編程語言

這篇文章主要介紹“如何調試大型開源項目ZooKeeper”,在日常操作中,相信很多人在如何調試大型開源項目ZooKeeper問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何調試大型開源項目ZooKeeper”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

一、源碼調試

> 授人以魚不如授人以漁

我始終相信 “紙上得來終覺淺”,最終讀者想要自己真正了解到 ZK 內部原理,閱讀源碼還是必不可少的,如果你們和我一樣也擁有肉眼 Debug 的能力,那其實可以不用大費周章搭建源碼調試環境,直接正面硬剛。

如何調試大型開源項目ZooKeeper

但是如果沒有的話,把 ZK 源碼下載下來,使用稱手的 IDE 直接跑起來,然后在需要學習的地方直接打斷點,豈不是美滋滋

如何調試大型開源項目ZooKeeper

1.1 下載源碼

ZooKeeper 3.6.2 源碼下載頁面

如何調試大型開源項目ZooKeeper

上面的鏈接中隨便選一個下載速度快的,點擊下載壓縮包即可,下載完成后解壓縮就會得到如下的目錄結構

.
├── zookeeper-server
├── zookeeper-recipes
├── zookeeper-metrics-providers
├── zookeeper-jute
├── zookeeper-it
├── zookeeper-docs
├── zookeeper-contrib
├── zookeeper-compatibility-tests
├── zookeeper-client
├── zookeeper-assembly
├── zk-merge-pr.py
├── pom.xml
├── owaspSuppressions.xml
├── excludeFindBugsFilter.xml
├── dev
├── conf
├── checkstyleSuppressions.xml
├── checkstyle-strict.xml
├── checkstyle-simple.xml
├── bin
├── README_packaging.md
├── README.md
├── NOTICE.txt
├── LICENSE.txt
├── Jenkinsfile-PreCommit
└── Jenkinsfile

目錄中是有 pom.xml 所以 ZK 需要通過 maven 編譯整個項目,先確保自己的 maven 是安裝好的

$ mvn --version
Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-18T02:33:14+08:00)
Maven home: /your/maven/home/apache-maven-3.5.4
Java version: 1.8.0_181, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre
Default locale: zh_CN, platform encoding: UTF-8
OS name: "mac os x", version: "10.16", arch: "x86_64", family: "mac"

如果有這樣的輸出說明 maven 是安裝成功的,具體安裝過程我這里就略過了,如果你有困難的話,可以留言給我們

1.2 編譯項目

進入和 pom.xml 同級目錄中并輸入

$ mvn install -DskipTests=true

就會看到項目在進行編譯了,等到最后的輸出 BUILD SUCCESS,就說明項目編譯完成了

[INFO] Reactor Summary:
[INFO]
[INFO] Apache ZooKeeper 3.6.2 ............................. SUCCESS [  3.621 s]
[INFO] Apache ZooKeeper - Documentation ................... SUCCESS [  2.086 s]
[INFO] Apache ZooKeeper - Jute ............................ SUCCESS [ 10.633 s]
[INFO] Apache ZooKeeper - Server .......................... SUCCESS [ 19.246 s]
[INFO] Apache ZooKeeper - Metrics Providers ............... SUCCESS [  0.108 s]
[INFO] Apache ZooKeeper - Prometheus.io Metrics Provider .. SUCCESS [  1.286 s]
[INFO] Apache ZooKeeper - Client .......................... SUCCESS [  0.083 s]
[INFO] Apache ZooKeeper - Recipes ......................... SUCCESS [  0.092 s]
[INFO] Apache ZooKeeper - Recipes - Election .............. SUCCESS [  0.244 s]
[INFO] Apache ZooKeeper - Recipes - Lock .................. SUCCESS [  0.259 s]
[INFO] Apache ZooKeeper - Recipes - Queue ................. SUCCESS [  0.295 s]
[INFO] Apache ZooKeeper - Assembly ........................ SUCCESS [  5.425 s]
[INFO] Apache ZooKeeper - Compatibility Tests ............. SUCCESS [  0.072 s]
[INFO] Apache ZooKeeper - Compatibility Tests - Curator 3.6.2 SUCCESS [  0.432 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 44.263 s
[INFO] Finished at: 2021-01-22T13:49:30+08:00
[INFO] ------------------------------------------------------------------------

1.3 打開并配置項目

之后就可以通過你的 IDE 打開這個目錄了,我這里使用的是 idea

如何調試大型開源項目ZooKeeper

然后開始配置 Run/Debug Configurations

如何調試大型開源項目ZooKeeper

點擊 + 添加新的配置

如何調試大型開源項目ZooKeeper

選擇 Application

如何調試大型開源項目ZooKeeper

1.3.1 單機版啟動配置

然后配置按照下圖去填寫或選擇

如何調試大型開源項目ZooKeeper

  1. 先給這個配置起一個牛逼的名字

  2. 選擇 Modify options 打開子菜單

  3. 確保圖中菜單中的三個子選項都被選中(前面有 √)

然后我們看具體的配置

如何調試大型開源項目ZooKeeper

在我電腦上解壓縮后的項目路徑為 /Users/junjiexun/Desktop/apache-zookeeper-3.6.2 讀者請根據自己情況修改

  1. 選擇你本地 jdk (我本地是 1.8 其他版本的不知道行不行,低版本肯定是不行,因為源碼中用到了 1.8 的一些寫法)

  2. 選擇 zookeeper

  3. 配置 VM options,內容為 -Dlog4j.configuration=file:/Users/junjiexun/Desktop/apache-zookeeper-3.6.2/conf/log4j.properties,如果不配置的話,無法輸出日志

  4. 指定啟動類 org.apache.zookeeper.server.ZooKeeperServerMain

  5. 單機版啟動需要命令行參數,內容為 2181 /Users/junjiexun/Desktop/apache-zookeeper-3.6.2/data

  6. 這個應該是不用修改,自動就會填上的,反正內容就是 /Users/junjiexun/Desktop/apache-zookeeper-3.6.2

  7. 點擊中間的 + 添加包路徑,內容為 org.apache.zookeeper.server.*

然后點擊 Apply 以及 OK 完成保存。

然后點擊這個小蟲子就可以啟動了

如何調試大型開源項目ZooKeeper

2021-01-22 15:12:16,319 [myid:] - INFO  [main:NIOServerCnxnFactory@674] - binding to port 0.0.0.0/0.0.0.0:2181
2021-01-22 15:12:16,413 [myid:] - INFO  [main:WatchManagerFactory@42] - Using org.apache.zookeeper.server.watch.WatchManager as watch manager
2021-01-22 15:12:16,413 [myid:] - INFO  [main:WatchManagerFactory@42] - Using org.apache.zookeeper.server.watch.WatchManager as watch manager
2021-01-22 15:12:16,413 [myid:] - INFO  [main:ZKDatabase@132] - zookeeper.snapshotSizeFactor = 0.33
2021-01-22 15:12:16,413 [myid:] - INFO  [main:ZKDatabase@152] - zookeeper.commitLogCount=500
2021-01-22 15:12:16,429 [myid:] - INFO  [main:SnapStream@61] - zookeeper.snapshot.compression.method = CHECKED
2021-01-22 15:12:16,432 [myid:] - INFO  [main:FileSnap@85] - Reading snapshot /Users/junjiexun/Desktop/apache-zookeeper-3.6.2/data/version-2/snapshot.2
2021-01-22 15:12:16,444 [myid:] - INFO  [main:DataTree@1737] - The digest value is empty in snapshot
2021-01-22 15:12:16,480 [myid:] - INFO  [main:ZKDatabase@289] - Snapshot loaded in 67 ms, highest zxid is 0x2, digest is 1371985504
2021-01-22 15:12:16,481 [myid:] - INFO  [main:FileTxnSnapLog@470] - Snapshotting: 0x2 to /Users/junjiexun/Desktop/apache-zookeeper-3.6.2/data/version-2/snapshot.2
2021-01-22 15:12:16,488 [myid:] - INFO  [main:ZooKeeperServer@529] - Snapshot taken in 6 ms
2021-01-22 15:12:16,544 [myid:] - INFO  [ProcessThread(sid:0 cport:2181)::PrepRequestProcessor@136] - PrepRequestProcessor (sid:0) started, reconfigEnabled=false
2021-01-22 15:12:16,546 [myid:] - INFO  [main:RequestThrottler@74] - zookeeper.request_throttler.shutdownTimeout = 10000
2021-01-22 15:12:16,623 [myid:] - INFO  [main:ContainerManager@83] - Using checkIntervalMs=60000 maxPerMinute=10000 maxNeverUsedIntervalMs=0
2021-01-22 15:12:16,628 [myid:] - INFO  [main:ZKAuditProvider@42] - ZooKeeper audit is disabled.

看到日志輸出,如果沒有報錯的話就是成功了!

然后我們可以用客戶端測試下

ZooKeeper client = new ZooKeeper("127.0.0.1:2181", 3000, null);
List<string> children = client.getChildren("/", false);
System.out.println(children);
client.close();

輸出為

[zookeeper]

單機版的搞定了!我們下面試試集群版

1.3.2 集群版啟動配置

我們有時候需要調試集群版 ZK 才有的邏輯,那之前的單機版就不夠用了,并且我這里推薦將之前的源碼壓縮包,解壓到兩個不同的目錄下,然后通過 IDE 分別打開這兩個目錄,去完全模擬兩個不同的節點。集群版的和單機版配置是差不多的,我們來看看有哪些不一樣的吧?我這里演示就啟動兩個節點 myid 分別是 1 和 2。

如何調試大型開源項目ZooKeeper

  1. 首先將默認的 zoo_sample.cfg 復制并重命名成 zoo.cfg,也可以直接重命名

  2. 新建 data 目錄(如果沒有的話),并在其下新建一個文本文件 myid 文本內容是 1

然后編輯下 zoo.cfg

# 修改
dataDir=/Users/junjiexun/Desktop/apache-zookeeper-3.6.2/data
# 新增下面兩行
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2887:3887

具體的配置如下:

如何調試大型開源項目ZooKeeper

  1. 啟動類不同,集群的為 org.apache.zookeeper.server.quorum.QuorumPeerMain

  2. 命令行參數不同,傳入的是 zoo.cfg 路徑,我的路徑是 /Users/junjiexun/Desktop/apache-zookeeper-3.6.2/conf/zoo.cfg

然后是配置第二個節點,我這里假設第二個節點的項目目錄是 /Users/junjiexun/Desktop/apache-zookeeper-3.6.2-bak

第二個節點把 myid 文件中的內容修改為 2

zoo.cfg 中內容是

# 修改
dataDir=/Users/junjiexun/Desktop/apache-zookeeper-3.6.2-bak/data
# 修改,因為我兩個節點是在一臺機器中的,所以端口是不能重復的
clientPort=2182
# 同樣新增下面兩行
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2887:3887

命令行的參數是 /Users/junjiexun/Desktop/apache-zookeeper-3.6.2-bak/conf/zoo.cfg

其他我沒提到的和節點 1 是一樣的。

我們啟動兩個節點試試

2021-01-22 15:44:08,461 [myid:1] - INFO  [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):WatchManagerFactory@42] - Using org.apache.zookeeper.server.watch.WatchManager as watch manager
2021-01-22 15:44:08,461 [myid:1] - INFO  [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):WatchManagerFactory@42] - Using org.apache.zookeeper.server.watch.WatchManager as watch manager
2021-01-22 15:44:08,471 [myid:1] - INFO  [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):Learner@677] - Learner received NEWLEADER message
2021-01-22 15:44:08,471 [myid:1] - INFO  [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):QuorumPeer@1811] - Dynamic reconfig is disabled, we don't store the last seen config.
2021-01-22 15:44:08,471 [myid:1] - INFO  [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):FileTxnSnapLog@470] - Snapshotting: 0x28100000001 to /Users/junjiexun/Desktop/apache-zookeeper-3.6.2/data/version-2/snapshot.28100000001
2021-01-22 15:44:08,472 [myid:1] - INFO  [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):ZooKeeperServer@529] - Snapshot taken in 1 ms
2021-01-22 15:44:08,525 [myid:1] - INFO  [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):Learner@661] - Learner received UPTODATE message
2021-01-22 15:44:08,525 [myid:1] - INFO  [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):QuorumPeer@868] - Peer state changed: following - synchronization
2021-01-22 15:44:08,537 [myid:1] - INFO  [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):CommitProcessor@476] - Configuring CommitProcessor with readBatchSize -1 commitBatchSize 1
2021-01-22 15:44:08,537 [myid:1] - INFO  [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):CommitProcessor@438] - Configuring CommitProcessor with 4 worker threads.
2021-01-22 15:44:08,544 [myid:1] - INFO  [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):RequestThrottler@74] - zookeeper.request_throttler.shutdownTimeout = 10000
2021-01-22 15:44:08,567 [myid:1] - INFO  [QuorumPeer[myid=1](plain=[0:0:0:0:0:0:0:0]:2181)(secure=disabled):QuorumPeer@863] - Peer state changed: following - broadcast

最后的 Peer state changed 代表選舉完成了,貼出來的這個節點 1 是 Follower,大功告成!

之后當你想要學習源碼的流程的時候,直接本地啟動服務端即可,是不是美滋滋呢~

1.4 源碼閱讀指北

  • 服務端啟動,集群 QuorumPeerMain#main,單機 ZooKeeperServerMain#main

  • 客戶端 ZooKeeper

  • 解析配置相關,QuorumPeerConfig#parse

  • 內存模型(小紅本)DataTree

  • 回調通知(小黃本)IWatchManager 查看該接口實現

    • 默認實現 WatchManager

    • 優化方案 WatchManagerOptimized

  • 選舉 FastLeaderElection#lookForLeader

  • 服務端實例,設置流水線 setupRequestProcessors 方法

    • Leader 節點 LeaderZooKeeperServer

    • Follower 節點 FollowerZooKeeperServer

    • Observer 節點 ObserverZooKeeperServer

  • 各個流水線員工 RequestProcessor 查看該接口的實現

  • 持久化 log FileTxnLog,snapshot FileSnap

  • 會話管理 SessionTrackerImpl#run

  • 協議 Record 查看該接口的實現

1.5 源碼閱讀心得

閱讀大型項目的源碼一定是一個費時費心費力的工作,我這里也講一下我閱讀 ZK 源碼的心得:

  • 不要死摳細節!大型項目的源碼數量通常比較多,如果盯著邏輯中的每一個細節,就會迷失在源碼的汪洋大海中。

  • 通常閱讀源碼都要帶著一個目的。例如:ZK 是怎么進行協議轉換的,ZK 是怎么選舉的等等。有了目的以后,看相關源碼是要選擇性的忽略一些其他不相關的細節,可以通過方法名或者注釋,來對具體的代碼塊先有一個感性的認識。

  • 碰到讀不懂的地方,可以先去網上看看有沒有人寫過類似的博客,站在巨人的肩膀上,很可能別人一點你就通了。

  • 在 ZK 中一般間接或者直接繼承 ZooKeeperThread 都是線程對象,主要邏輯可以查看 run 方法。

  • 任何一個類重要的屬性肯定是在成員字段中,通過查看成員字段是可以大致推測出該類背后的數據結構。

  • 成員屬性中如果有阻塞隊列的字段,大概率會是生產者-消費者模式的體現,可以重點關注該阻塞隊列的使用,何時放入以及取出元素。

1.6 小結

我用一些圖文的篇幅介紹了如何在本地調試 ZK 源碼,以及如何科學的閱讀源碼。我本地的環境是 Mac,用的 IDE 是 idea,如果你的環境或者工具和我不一樣,碰到了困難的話,也可以給我們留言哦~

二、ZK 中應用到的設計模式

ZK 本身就是分布式的應用,也是優秀的開源項目,我這里就簡單聊聊我在閱讀源碼中看到的應用在 ZK 里的設計模式吧

2.1 生產者消費者

這個是 ZK 中非常有代表性的設計模式應用了,ZK 本身是 C/S 架構的設計,請求就是客戶端發送給服務端數據,響應則是服務端發送給客戶端數據,而 ZK 實現一些功能并不是通過線性順序的去調用不同的方法去完成的,通常會由生產者線程,阻塞隊列和消費者線程組成,生產者線程將上游收到的一些請求對象放入阻塞隊列,當前的方法就返回了,之后由消費者線程通過循環不停的從阻塞隊列中獲取,再完成之后的業務邏輯。舉例:

  • PrepRequestProcessor,阻塞隊列是 submittedRequests

  • SyncRequestProcessor,阻塞隊列是 queuedRequests

2.2 工廠模式

有一些接口的實現,ZK 本身提供了默認的選擇,但是如果使用者在配置中配置了其他的實現的話,ZK 的工廠就會自動去創建那些其他的實現。舉例:

  • 在創建 ClientCnxnSocket 時,會根據 zookeeper.clientCnxnSocket 的配置去選擇客戶端的 IO 實現

  • 在創建 IWatchManager 時,會根據 zookeeper.watchManagerName 的配置去選擇服務端的 watch 管理實現

  • 在創建 ServerCnxnFactory 時,會根據 zookeeper.serverCnxnFactory 的配置去選擇服務端的 IO 工廠實現

2.3 責任鏈模式

之前有學習過,ZK 服務端業務邏輯處理是通過將一個個 XxxProcessor 串起來實現的,Processor 彼此不關心調用順序,僅僅通過 nextProcessor 關聯,不同的服務端角色也可以通過這種方式極大的復用代碼

  • 單機模式下:PrepRequestProcessor -&gt; SyncRequestProcessor -&gt; FinalRequestProcessor

  • 集群模式下 Leader :LeaderRequestProcessor -&gt; PrepRequestProcessor -&gt; ProposalRequestProcessor -&gt; CommitProcessor -&gt; Leader.ToBeAppliedRequestProcessor -&gt; FinalRequestProcessor

  • 集群模式下 Follower :FollowerRequestProcessor -&gt; CommitProcessor -&gt; FinalRequestProcessor

  • 集群模式下 Observer :ObserverRequestProcessor -&gt; CommitProcessor -&gt; FinalRequestProcessor

2.4 策略模式

zookeeper.snapshot.compression.method 可以配置成不同的 snapshot 壓縮算法,當需要生成 snapshot 文件的時候,會根據不同的壓縮算法去執行:

  • gzGZIPInputStream

  • snappySnappyInputStream

  • 默認:BufferedInputStream

2.5 裝飾器模式

還是剛剛的壓縮算法,對外提供的是 CheckedInputStream 的統一處理對象,使用 CheckedInputStream 將上面三種壓縮實現包裝起來,這些對象全部都是 InputStream 的子類

switch (根據不同的配置) {
  // 策略模式的體現
  case GZIP:
    is = new GZIPInputStream(fis);
    break;
  case SNAPPY:
    is = new SnappyInputStream(fis);
    break;
  case CHECKED:
  default:
    is = new BufferedInputStream(fis);
}
// 都被包裝進了 CheckedInputStream
// 裝飾器模式的體現
return new CheckedInputStream(is, new Adler32());

到此,關于“如何調試大型開源項目ZooKeeper”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

张家川| 洛宁县| 化州市| 白城市| 镇江市| 丽江市| 花莲市| 锡林郭勒盟| 佳木斯市| 沙湾县| 泰州市| 吉林市| 嘉荫县| 定州市| 禄劝| 岳阳县| 七台河市| 鄂伦春自治旗| 石门县| 通化县| 会泽县| 青浦区| 德昌县| 虹口区| 阜南县| 仲巴县| 五峰| 通化市| 上虞市| 新竹市| 军事| 江山市| 景德镇市| 嫩江县| 海淀区| 金坛市| 朝阳县| 霍城县| 黄陵县| 丰都县| 永州市|