kafka源碼閱讀之MacBook Pro M1搭建Kafka2.7版本源碼運行環境

image

原創/朱季謙

最近在閱讀Kafka的源碼,想可以在閱讀過程當中,在代碼寫一些註釋,便決定將源碼部署到本地運行。

日常開發過程中,用得比較多一個版本是Kafka2.7版本,故而在MacBook Pro筆記本上用這個版本的源碼進行搭建,進行Kafka源碼的閱讀學習。在搭建的過程當中,遇到不少坑,順便記錄了下來,方便以後重新搭建時,不至於又從頭開始。

在本地搭建Kafka2.7源碼,需要準備以下環境,我本地用的是MacBook Pro M1筆記本,windows的話應該也是類似思路:

  • Zulu JDK1.8
  • Scala 2.13.1
  • Gradle6.6
  • Zookeeper3.4.6
  • Kafka2.7

基於以上需要的環境,一一講解。

一、Zulu JDK1.8

這個沒啥好講的,基本用MBP做開發的,幾乎都有安裝了一個JDK,區別是不同版本而已。我用的是OpenJDK 的Zulu JDK1.8版本,印象中是可以通過直接下載 .dmg 格式一鍵安裝的,同時會自動配置好系統環境,默認安裝路徑在 /Library/Java/JavaVirtualMachines。

二、Scala 2.13.1

我沒有在系統裏安裝Scala,而是直接用IDEA的。

按照Preferences -> Plugins -> 選擇Scala點擊Installed。
image

這樣可以基於IDEA選擇不同版本的Scala JDK——
image

三、安裝Gradle6.6

可以通過官網https://gradle.org/releases/下載Gradle6.6版本——
image

官網下載,若是國內下載會很慢,我將當時下載的安裝包放在了百度網盤裏,可以直接網盤下載——

網盤鏈接: https://pan.baidu.com/s/1zmV2LNan0-lNEndPZ-H_Qw 提取碼: agu5

下載下來後,直接解壓,我放在了目錄/Users/helloword/software/gradle-6.6,在mac終端執行指令——

vim ~/.bash_profile 

在bash_profile文件里加入以下內容,這裏的GRADLE_HOME即解壓存放gradle-6.6的目錄——

GRADLE_HOME=/Users/helloword/software/gradle-6.6
export GRADLE_HOME

保存,執行source ~/.bash_profile刷新,輸入gradle -v驗證一下,若是出現以下信息,表示gradle安裝成功——

zhujiqian@zhujiqiandeMacBook-Pro ~ % gradle -v

------------------------------------------------------------
Gradle 6.6
------------------------------------------------------------

Build time:   2020-08-10 22:06:19 UTC
Revision:     d119144684a0c301aea027b79857815659e431b9

Kotlin:       1.3.72
Groovy:       2.5.12
Ant:          Apache Ant(TM) version 1.10.8 compiled on May 10 2020
JVM:          1.8.0_282 (Azul Systems, Inc. 25.282-b08)
OS:           Mac OS X 12.5.1 aarch64

三、Zookeeper3.4.6安裝

同理,避免讀者額外去找這個包,我把它放到了百度網盤上——

鏈接: https://pan.baidu.com/s/1sTJVzDH5q4Jw5biAzTs3Mw 提取碼: 6v87

3.1、分別將zookeeper-3.4.6.tar.gz拷貝到三臺機器上,例如下面三臺機器上,放到app目錄下——

服務器名字 服務器IP
hadoop1 192.168.31.130
hadoop2 192.168.31.131
hadoop3 192.168.31.132

3.2、在三臺機器的/app/zookeeper-3.4.6目錄下,各創建一個data目錄,然後各建立一個命名爲myid的文件,分別按照以下方式寫入一個數字——

  • 192.168.31.130的/app/zookeeper-3.4.6/data/myid寫入數字1
  • 192.168.31.130的/app/zookeeper-3.4.6/data/myid寫入數字2
  • 192.168.31.130的/app/zookeeper-3.4.6/data/myid寫入數字3

cat查看192.168.31.130的/app/zookeeper-3.4.6/data/myid,值爲1——
image

3.3、在192.168.31.130的/app/zookeeper-3.4.6/conf/目錄下,其本身就有一個zoo_sample.cfg文件,通過cp zoo_sample.cfg zoo.cfg指令複製生成一個zoo.cfg文件,在zoo.cfg文件裏修改爲以下內容——

tickTime=2000
initLimit=10
syncLimit=5
dataDir=/app/zookeeper-3.4.6/data
quorumListenOnAllIPs=true
clientPort=2181
dataLogDir=/app/zookeeper-3.4.6/dataLog
server.1=192.168.31.130:2888:3888
server.2=192.168.31.131:2888:3888
server.3=192.168.31.132:2889:3889

保存完成後,分別複製到192.168.31.131、192.168.31.132這兩臺機器的/app/zookeeper-3.4.6/conf/目錄下——

scp zoo.cfg [email protected]:/app/zookeeper-3.4.6/conf/
scp zoo.cfg [email protected]:/app/zookeeper-3.4.6/conf/

3.4、然後,就可以正常啓動了,分別在三臺機器的/app/zookeeper-3.4.6/bin目錄下,執行./zkServer.sh start,執行完成後,通過指令執行./zkServer.sh status 觀察集羣狀態,若是如下mode字段顯示follower或者leader的話,說明集羣已經成功啓動——
image

四、Kafka2.7源碼部署

4.1、源碼部署搭建

讀者可以自行到官網https://kafka.apache.org/downloads下載
image

當然,也可以直接從網盤下載,我已經放到網盤了,後續等我閱讀完後,會把有源碼註釋的,同步到網盤裏——

鏈接: https://pan.baidu.com/s/1KhW8V5UIcgtvXlCfAMNZeA 提取碼: 31te

我把源碼下載到目錄/Users/helloword/software/kafka/kafka-2.7.0-src裏。

Kafka源碼需要依賴Gradle構建代碼,就類似SpringBoot依賴Maven來構建代碼,故而在將Kafka源碼導入Idea前,先通過Gradle命令進行環境構建。

打開mac的終端,進入到源碼路徑——
image

然後分別執行以下指令——

#更新gradle
gradle
#只需執行一次,會在當前目錄的/gradle/wrapper/目錄裏生成一個gradle-wrapper.jar
gradle wrapper

執行以上指令後,主要生成一個gradle-wrapper.jar,它是用來構建項目及打包的。
image

接下來,分別繼續執行以下指令,這部分指令運行很慢,需要一段時間——

#在 Gradle 項目中構建可執行的 JAR 文件
./gradlew jar
#構建的項目中生成 IntelliJ IDEA 的工程文件和配置,若是用的eclipse,就運行./gradlew eclipse
./gradlew idea
#生成源代碼 JAR 文件
./gradlew srcJar

執行完以上指令,完成Gradle的代碼運行環境,就可以通過Idea導入Kafak2.7源碼——

正常情況下,左邊欄會出現Gradle菜單選項,若沒有的話,就雙擊源碼裏的build.gradle後,選擇Link Gradle Project——
image

這時候,源碼項目真正成爲一個Gradle構建的項目,可以看到右邊菜單多了一個Gradle菜單選項,點擊,可以看到Gradle欄目裏出現了一個kafka-2.7.0-src,雙擊後,選擇Reload Gradle Project就可以加載項目及依賴了。
image

4.2、源碼運行

4.2.1、源碼運行打印日誌

若要在源碼裏運行能夠打印日誌,需要滿足以下兩個條件——

1、複製config的log4.properties到core的 resources目錄

2、在build.gradle的project(':core') 的dependencies {}增加log4配置

4.2.1.1、複製config的log4.properties到core的 resources目錄

在源碼/core/src/main/目錄下,新建一個resource資源目錄。

而在源碼的config目錄下,有一個log4j.properties。

可以直接將/config/log4j.properties複製到/core/src/main/resources目錄裏——
image

當然,直接複製過來時,運行時,可能只會出現以下打印,發現log4j.properties並沒有起作用——
image

這時候就需要接下來在build.gradle增加一些配置。

4.2.1.2、在build.gradle的project(':core') 的dependencies {}增加log4配置

在build.gradle裏找到project(':core') {}裏的dependencies {}處,增加以下配置——

compile group: 'org.slf4j', name: "slf4j-api", version: "1.7.28"
compile group: 'org.slf4j', name: "slf4j-log4j12", version: "1.7.28"

image

配置完以上信息後,運行日誌時可能還會出現以下異常——

log4j:ERROR setFile(null,true) call failed.
java.io.FileNotFoundException: /server.log (Read-only file system)
	at java.io.FileOutputStream.open0(Native Method)
	at java.io.FileOutputStream.open(FileOutputStream.java:270)
	at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
	at java.io.FileOutputStream.<init>(FileOutputStream.java:133)
	at org.apache.log4j.FileAppender.setFile(FileAppender.java:294)
	at org.apache.log4j.FileAppender.activateOptions(FileAppender.java:165)
	at org.apache.log4j.DailyRollingFileAppender.activateOptions(DailyRollingFileAppender.java:223)

我當時的解決該異常的方式是,統一將log4.properties的日誌出現以上異常的路徑${kafka.logs.dir}改成指定的/Users/helloword/logs例如,/server.log等,統一改成,就正常了/Users/helloword/logs/server.log,就正常了。
image

4.2.2、修改源碼的config/server.properties配置

在運行kafka服務前,需要修改config/server.properties配置裏一些信息,主要改兩處地方,分別是連接的zookeeper路徑和kafka的broker的ip——

broker.id=0  #默認的就好
listeners=PLAINTEXT://192.168.31.110:9092  #改成你的主機ip,需要注意一點是,該ip需要能跟你配置的zookeeper通信
zookeeper.connect=192.168.31.130:2181,192.168.31.130:2181,192.168.31.130:2181 #zookeeper集羣地址

4.2.3、配置Kakfa運行的server、consumer、producer三個進程

4.2.3.1、server

按照以下信息配置一個server應用服務——
image

配置完,點擊啓動,若打印類似以下正常日誌,說明成功了——
image

4.2.3.2、consumer

這裏的--topic test01 --bootstrap-server 192.168.31.110:9092裏的ip,即配置config/server.properties文件裏listeners=PLAINTEXT://192.168.31.110:9092對應的ip。

該消費者表示監聽topic爲test01。
image

運行正常,日誌打印同樣沒問題——
image

4.2.3.3、producer

跟consumer配置類似——
image

配置完成後,運行,若沒有問題,可以直接在日誌控制嘗試模擬生產者發送消息,例如,發送一個hello world——
image

查看consumer端的日誌打印,若能收到消息,說明kafka的生產者和消費者能正常進行消息發送了,可以基於這開始debug閱讀源碼了——
image

整個kafka2.7版本源碼搭建,按照以上步驟就搭建完成。

後續我會將閱讀源碼的總結寫成系列文章。

最近開了一個公衆號,方便用來分類歸納自己寫的博客,可以關注我的公衆號【寫代碼的朱季謙】。
image

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章