記錄一下Mac下使用IDEA導入zookeeper源碼,並debug測試的過程,全文參考了文末博文。
源碼准備
github下載源碼,地址為https://github.com/apache/zookeeper,選擇對應的分支進行下載,這里選擇的是3.4.14。
安裝ant
官網(https://ant.apache.org/bindownload.cgi)下載ant,選擇對應的版本。
配置環境變量,修改~/.bash_profile,添加ant的安裝信息。
(base) [yangchaolin@youngchaolin-Mac.local ~/apache-ant-1.9.15/bin]$ vim ~/.bash_profile
添加ant的安裝信息。
# ant的解壓目錄
export ANT_HOME=/Users/yangchaolin/apache-ant-1.9.15
# 添加環境變量
export PATH=$PATH:$ANT_HOME/bin
讓新添加的信息生效。
(base) [yangchaolin@youngchaolin-Mac.local ~/apache-ant-1.9.15/bin]$ source ~/.bash_profile
使用ant -version命令查看,是否成功安裝,如下所示即為成功安裝。
(base) [yangchaolin@youngchaolin-Mac.local ~/apache-ant-1.9.15/bin]$ ant -version
Apache Ant(TM) version 1.9.15 compiled on May 10 2020
源碼構建
進入zookeeper源碼目錄,使用ant eclipse命令,將項目編譯並轉化為eclipse的項目結構。
(base) [yangchaolin@youngchaolin-Mac.local ~/zookeeper-branch-3.4.14]$ ant eclipse
Buildfile: /Users/yangchaolin/zookeeper-branch-3.4.14/build.xml
編譯過程比較長,大概幾分鍾左右。
(base) [yangchaolin@youngchaolin-Mac.local ~/zookeeper-branch-3.4.14]$ ant eclipse
Buildfile: /Users/yangchaolin/zookeeper-branch-3.4.14/build.xml
ant-eclipse-download:
init:
ivy-download:
ivy-taskdef:
ivy-init:
ivy-retrieve:
[ivy:retrieve] :: Apache Ivy 2.4.0 - 20141213170938 :: http://ant.apache.org/ivy/ ::
[ivy:retrieve] :: loading settings :: file = /Users/yangchaolin/zookeeper-branch-3.4.14/ivysettings.xml
[ivy:retrieve] :: resolving dependencies :: org.apache.zookeeper#zookeeper;3.4.14
# 過程略
---------------------------------------------------------------------
| | modules || artifacts |
| conf | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
| test | 93 | 0 | 0 | 0 || 93 | 0 |
---------------------------------------------------------------------
[eclipse] Writing the preferences for "org.eclipse.jdt.core".
[eclipse] Writing the preferences for "org.eclipse.core.resources".
[eclipse] Writing the project definition in the mode "java".
[eclipse] Writing the classpath definition.
BUILD SUCCESSFUL
IDEA導入
首先import導入。
選擇eclipse導入方式。
完成導入。
debug運行
接下來,以更新一條節點數據為例,選擇在IDEA啟動client進行更新,在linux服務器中啟動zookeeper集群。
如圖,在IDEA中配置一個代表client的application,文末博文是有配置本地zookeeper/conf目錄下的zoo.cfg,這里選擇不配置,選擇默認的配置即可,本地復制一份模板文件重命名為zoo.cfg。
另外打印日志相關的log4j需要配置,其他配置如下圖。
log4j配置。
# /Users/yangchaolin/zookeeper-branch-3.4.14就是${zookeeper_home}
-Dlog4j.configuration=file:/Users/yangchaolin/zookeeper-branch-3.4.14/conf/log4j.properties
關於事務id如cZxid,博文中有提到,由epoch+counter組成,各32位,其中高位是epoch,低位是counter,但是查看實際的事務id,epoch的位數顯示沒有32位,那是因為高位的0都被省略了,而低位的counter由於其還存在高位的epoch,因此32位都顯示。
debug模式下更新節點數據,最后打印是需要調用ZooKeeperMain類下的printStat方法,其中Stat實體類中就封裝了事務id。
private static void printStat(Stat stat) {
System.err.println("cZxid = 0x" + Long.toHexString(stat.getCzxid()));
System.err.println("ctime = " + new Date(stat.getCtime()).toString());
System.err.println("mZxid = 0x" + Long.toHexString(stat.getMzxid()));
System.err.println("mtime = " + new Date(stat.getMtime()).toString());
System.err.println("pZxid = 0x" + Long.toHexString(stat.getPzxid()));
System.err.println("cversion = " + stat.getCversion());
System.err.println("dataVersion = " + stat.getVersion());
System.err.println("aclVersion = " + stat.getAversion());
System.err.println("ephemeralOwner = 0x"
+ Long.toHexString(stat.getEphemeralOwner()));
System.err.println("dataLength = " + stat.getDataLength());
System.err.println("numChildren = " + stat.getNumChildren());
}
debug過程可以看到,事務id都是Long類型,這個可推理出是由64位epoch+counter二進制數據換算成的十進制的Long類型數據。
- cZxid:103079215134L
- mZxid :107374182416L
- pZxid :103079215149L
通過上面Long.toHexString(stat.getCzxid()))轉換后,Long類型再轉換為十六進制,就顯示如下的結果,給人一種高位的epoch沒有32位的假象,其實是因為epoch太小,且它前面沒有像counter一樣還有高位非0位,所以顯示省略了前面0的情況。
通過一段代碼可以打印出上面事務id對應的二進制形式。
/**
* 測試類,Long轉16進制
*/
public class ZookeeperTest {
@Test
public void testZxid(){
//cZxid
System.out.println("0x"+Long.toHexString(103079215134L));
System.out.println(Long.toBinaryString(103079215134L));
//mZxid
System.out.println("0x"+Long.toHexString(107374182416L));
System.out.println(Long.toBinaryString(107374182416L));
//pZxid
System.out.println("0x"+Long.toHexString(103079215149L));
System.out.println(Long.toBinaryString(103079215149L));
}
}
打印結果如下。
0x180000001e
1100000000000000000000000000000011110
0x1900000010
1100100000000000000000000000000010000
0x180000002d
1100000000000000000000000000000101101
補全高位,結果如下,為了閱讀方便按4位隔開。
0x180000001e
//cZxid補全后的結果
0000 0000 0000 0000 0000 0000 0001 1000 0000 0000 0000 0000 0000 0000 0001 1110
0x1900000010
//mZxid補全后的結果
0000 0000 0000 0000 0000 0000 0001 1001 0000 0000 0000 0000 0000 0000 0001 0000
0x180000002d
//pZxid補全后的結果
0000 0000 0000 0000 0000 0000 0001 1000 0000 0000 0000 0000 0000 0000 0010 1101
查看zookeeper客戶端,跟上面IDEA控制台數據一致,說明本地client debug測試沒有問題。
以上,就是zookeeper源碼導入IDEA的過程,並且可以通過debug查看自己想看的業務代碼線。
參考博文
(1)https://blog.csdn.net/moxiaomo0804/article/details/104249596