0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

閱讀開(kāi)源項(xiàng)目源碼的實(shí)用技巧(上)

jf_78858299 ? 來(lái)源:labuladong ? 作者:labuladong ? 2023-04-12 11:34 ? 次閱讀

本文分享一下在使用或者學(xué)習(xí)開(kāi)源項(xiàng)目源碼的過(guò)程中的一些經(jīng)驗(yàn)技巧。

因?yàn)槲易罱谘芯?Apache Pulsar 這款消息隊(duì)列,所以就以這個(gè)項(xiàng)目為例, 不過(guò)本文介紹的都是通用的技巧,完全可以用在其他大型開(kāi)源項(xiàng)目中 。

下面就來(lái)具體介紹一些技巧,主要分兩部分:

第一部分是文檔篇,即能夠哪里能夠獲取有效的信息解決問(wèn)題;

第二部分是實(shí)操篇,即如何高效打斷點(diǎn)或借助工具理解源碼。

一、文檔檢索技巧

想學(xué)習(xí)了解一個(gè)開(kāi)源項(xiàng)目,文檔可以幫我們解決大部分問(wèn)題。當(dāng)然我這里所說(shuō)的不單單指官網(wǎng)文檔,還包括 issue、PR、源碼中的注釋和單元測(cè)試,這些地方都可以獲得大量有用的信息,所以我把它們統(tǒng)稱為文檔,下面我們從最簡(jiǎn)單的開(kāi)始。

1、官網(wǎng)文檔,著重 quickstart 和 concept 部分 。

官網(wǎng)文檔無(wú)疑是最權(quán)威的資料來(lái)源,不過(guò)官網(wǎng)文檔的問(wèn)題是內(nèi)容太多太全面,適合遇到問(wèn)題或需求時(shí)當(dāng)做功能手冊(cè)去查閱。

所以官網(wǎng)的內(nèi)容需要選擇性地學(xué)習(xí),我建議優(yōu)先著重兩個(gè)部分:

一是 quickstart 部分,也就是教你如何快速部署一個(gè) demo 服務(wù);二是 concept 部分,也就是名詞解釋、核心功能介紹等內(nèi)容。

快速部署 demo 服務(wù)不用說(shuō)了,是我們學(xué)習(xí)新技術(shù)的第一步,一般會(huì)被放在文檔的第一章;而功能/名詞的解釋是我們接下來(lái)順暢地學(xué)習(xí)進(jìn)階資料或參與社區(qū)討論的重要鋪墊。

對(duì) Pulsar 這樣一個(gè)消息隊(duì)列來(lái)說(shuō),收發(fā)消息顯然是核心功能,所以官網(wǎng) Concepts and Architecture 部分中的 Messaging 章節(jié)顯然是很重要的,詳細(xì)介紹了 Pulsar 中諸如訂閱模式、死信隊(duì)列等關(guān)鍵功能:

圖片

我在前文 Apache Pulsar 架構(gòu)設(shè)計(jì) 介紹到 Pulsar 采用存算分離的架構(gòu),存儲(chǔ)層依靠 Apache Bookkeeper。所以如果你的目標(biāo)是學(xué)習(xí) Pulsar,那么 Bookkeeper 的官網(wǎng)文檔也是需要閱讀的,因?yàn)?Pulsar 中的很多功能都會(huì)和 Bookkeeper 交互。

可以在本地啟一個(gè) Bookkeeper 集群用 client 玩一玩,閱讀了解一下 Bookkeeper 中的專業(yè)術(shù)語(yǔ),有助于理解 Pulsar 中的一些設(shè)計(jì)。

2、看完文檔看單元測(cè)試用例,輔助我們準(zhǔn)確理解每個(gè)功能的預(yù)期行為 。

一般成熟開(kāi)源項(xiàng)目的測(cè)試用例比較完備,會(huì)覆蓋所有關(guān)鍵功能的預(yù)期行為,所以單測(cè)用例其實(shí)也是很好的學(xué)習(xí)資料,和文檔搭配食用效果最佳。

比方說(shuō),有時(shí)候文檔用文字描述某個(gè)功能可能會(huì)比較繁瑣,讓人看的云里霧里,又或者文檔中并沒(méi)有介紹一些技術(shù)設(shè)計(jì)的細(xì)節(jié)。

遇到這種情況,我們大概率可以在單測(cè)文件中找到對(duì)應(yīng)的功能測(cè)試代碼,根據(jù)測(cè)試代碼很容易反推功能,正所謂「talk is cheap, show me the code」。

舉個(gè)例子,有一次我看到 consumer 打出一條關(guān)于epoch的日志,我在分布式選主的場(chǎng)景倒是聽(tīng)說(shuō)過(guò)這個(gè)名詞,不過(guò)顯然消費(fèi)消息和分布式選主沒(méi)什么關(guān)系,所以這個(gè)epoch到底是干什么的?

文檔里沒(méi)找到答案,這應(yīng)該是一個(gè)具體實(shí)現(xiàn)中的術(shù)語(yǔ),所以我就在源碼中搜索包含testEpochepochTest這兩個(gè)關(guān)鍵詞的函數(shù)名,發(fā)現(xiàn)了幾個(gè)測(cè)試用例:

圖片

PS:測(cè)試函數(shù)名的 test 關(guān)鍵字可能在開(kāi)頭也可能在最后,所以需要都搜一下。

瀏覽了一下這幾個(gè)測(cè)試用例的內(nèi)容就大致理解了,原來(lái)這個(gè)epoch是消息重投遞功能(redelivery)中的一個(gè)術(shù)語(yǔ),主要用于防止重復(fù)消費(fèi)消息。

3、善用 GitHub,從項(xiàng)目的 issue/PR/wiki 列表獲取有效信息 。

首先,issue 列表不用多說(shuō)了,如果你在使用軟件的過(guò)程中遇到了問(wèn)題,首先考慮的就是去 issue 列表搜索。

雖然有時(shí)候搜出來(lái)的并不是直接的答案,但多換關(guān)鍵詞搜幾次,大概率就能找到一些思路解決問(wèn)題了。

另外, PR 信息可以幫助我們了解某些代碼片段的上下文背景 。

舉個(gè)例子,比如你閱讀某段代碼時(shí)有疑惑,不明白這個(gè)代碼的目的是什么,那么可以在 IDEA 中的代碼左側(cè)單擊右鍵,打開(kāi)「Annotate with Git Blame」就可看到這段代碼是誰(shuí)在什么時(shí)候添加上去的:

圖片

然后把鼠標(biāo)懸停在作者昵稱上兩秒,就會(huì)彈出這個(gè)代碼被合進(jìn) master 分支時(shí)的 PR 標(biāo)題和鏈接:

圖片

18260就是這個(gè) PR 的編號(hào),點(diǎn)擊即可跳轉(zhuǎn)到對(duì)應(yīng)的 PR 頁(yè)面:

圖片

可以看到這個(gè) PR 是用來(lái)修復(fù)18241號(hào) issue 的,在18241號(hào) issue 中詳細(xì)描述了 bug 信息及復(fù)現(xiàn)方法:

圖片

有了這些上下文信息,就可以避免我們閱讀源碼時(shí)的障礙了。

最后, wiki 頁(yè)面可以幫我們了解一些重要的功能設(shè)計(jì)或改動(dòng) 。

拿 Pulsar 來(lái)說(shuō),如果需要做比較重要的改動(dòng),需要提出一個(gè) PIP 提案(Pulsar Improvement Proposal),也就是一個(gè)專門講解背景信息、設(shè)計(jì)思路的文檔。

而這些 PIP 文檔就收集在 wiki 頁(yè)面:

圖片

所以在了解某個(gè)功能模塊的設(shè)計(jì)思路時(shí),可以先去 wiki 頁(yè)面看看是否有相關(guān)的 PIP 可供參考。

比如 Pulsar 的事務(wù)實(shí)現(xiàn),就有一個(gè)專門的 PIP 詳細(xì)介紹了設(shè)計(jì)思路,結(jié)合 PIP 的思路指引去學(xué)習(xí)源碼就會(huì)容易很多:

圖片

我個(gè)人覺(jué)得,好的 PIP 結(jié)合源碼,帶我們把一個(gè)功能從討論設(shè)計(jì)做到落地實(shí)現(xiàn),這就是很好的教科書(shū)呀,多花精力去研究,肯定會(huì)有所收獲的。

以上就是最常用的有效信息的獲取途徑,如果你在學(xué)習(xí)使用開(kāi)源項(xiàng)目時(shí)遇到問(wèn)題,那么可以嘗試上述的方法去尋找答案。

當(dāng)然,熟練掌握進(jìn)行信息檢索的工具進(jìn)行高效檢索也是重要的技能,比如說(shuō) IDEA 的各種搜索、GitHub issue/PR 的搜索語(yǔ)法,這些技巧網(wǎng)上可以很容易搜到,我就不贅述了。

二、源碼閱讀技巧

想真正了解一個(gè)項(xiàng)目,看源碼肯定是逃不掉的一環(huán)。閱讀源碼的好處不用多說(shuō)了,但閱讀源碼肯定會(huì)花費(fèi)大量時(shí)間,而且這個(gè)過(guò)程不會(huì)很輕松。

你想嘛,成熟的開(kāi)源項(xiàng)目經(jīng)過(guò)多年的發(fā)展,功能不斷演進(jìn),很多人往里面寫過(guò)代碼,恐怕沒(méi)人能保證自己完全了解系統(tǒng)的每個(gè)細(xì)節(jié)。我們閱讀源碼,就好比探索一座龐大的城市,很容易迷失在某個(gè)犄角旮旯。

對(duì)于這個(gè)問(wèn)題,我可以分享一些小技巧。

技巧一、不建議看「死代碼」,建議在調(diào)試實(shí)際問(wèn)題的過(guò)程中理解代碼 。

換句話說(shuō),不要拿著代碼硬讀,最好是通過(guò)動(dòng)態(tài)調(diào)試來(lái)研究每個(gè)功能中做了什么。

拿 Pulsar 舉例,我們可以在命令行啟動(dòng) standalone 模式的 Pulsar broker:

$ bin/pulsar standalone

然后用 Java client 創(chuàng)建一個(gè) producer 發(fā)送一條消息:

PulsarClient client = PulsarClient.builder()
        .serviceUrl("pulsar://localhost:6650")
        .build();

Producer<byte[]> producer = client.newProducer()
        .topic("testTopic")
        .create();

MessageId messageId1 = producer.send(("hello1").getBytes());

client.close();

我們就可以調(diào)試這個(gè)簡(jiǎn)單的場(chǎng)景,看看 producer 是如何創(chuàng)建的,消息是如何發(fā)送并存儲(chǔ)在 Pulsar 中的。

但如果想跟蹤調(diào)試這段代碼,會(huì)遇到一些問(wèn)題:

第一個(gè)問(wèn)題是,我們自己的項(xiàng)目是通過(guò) Maven 引入 client 包的,如果進(jìn)入這些包看到的是反編譯的 class 文件,無(wú)法直接看到源碼。就算 IDEA 可以直接幫我們下載源碼,但如果我們?cè)趶氖?client 的開(kāi)發(fā),需要 master 分支的最新版代碼,這和上傳到 Maven 的源碼還是不一樣。

這個(gè)問(wèn)題比較容易解決,我們直接從 GitHub 下載源碼,在 client 包里面創(chuàng)建一個(gè) test 文件寫邏輯,這樣就可以調(diào)試最新的 client 代碼了。

第二個(gè)問(wèn)題比較棘手,我們想調(diào)通整個(gè) Pulsar 發(fā)送消息的流程,那么這里面肯定要涉及 Pulsar client 和 Pulsar broker 的交互,而 broker 是通過(guò)命令行啟動(dòng)的,我如何調(diào)試 broker 里面的代碼呢?

我們可以觀察一下,bin/pulsar這個(gè)文件其實(shí)就是個(gè) shell 腳本,可以找到這樣一段代碼:

elif [ $COMMAND == "standalone" ]; then
    PULSAR_LOG_FILE=${PULSAR_LOG_FILE:-"pulsar-standalone.log"}
    exec $JAVA $LOG4J2_SHUTDOWN_HOOK_DISABLED $OPTS ${ZK_OPTS} -Dpulsar.log.file=$PULSAR_LOG_FILE -Dpulsar.config.file=$PULSAR_STANDALONE_CONF org.apache.pulsar.PulsarStandaloneStarter $@

standalone命令其實(shí)就是運(yùn)行java命令,輸入一大堆參數(shù),加載了一堆 jar 包,最終啟動(dòng)了PulsarStandaloneStarter這個(gè)類,所以我們可以使用 JVM 遠(yuǎn)程調(diào)試功能 。

IDE 就給我們提供了 Remote JVM Debug 功能:

圖片

我新建一個(gè)遠(yuǎn)程調(diào)試,參數(shù)填默認(rèn)的就行,這里 IDE 給我們自動(dòng)生成了一段 JVM 參數(shù):

圖片

我們把這段 JVM 參數(shù)復(fù)制,把其中的suspend=n改成suspend=y,然后修改bin/pulsar文件,把這段參數(shù)添加到standalone模式的啟動(dòng)參數(shù)中:

elif [ $COMMAND == "standalone" ]; then
    # 添加調(diào)試參數(shù),注意 suspend=y
    OPTS="${OPTS} -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005"

    PULSAR_LOG_FILE=${PULSAR_LOG_FILE:-"pulsar-standalone.log"}
    exec $JAVA $LOG4J2_SHUTDOWN_HOOK_DISABLED $OPTS ${ZK_OPTS} -Dpulsar.log.file=$PULSAR_LOG_FILE -Dpulsar.config.file=$PULSAR_STANDALONE_CONF org.apache.pulsar.PulsarStandaloneStarter $@

這樣,我們本地命令行再執(zhí)行執(zhí)行bin/pulsar standalone時(shí)就會(huì)掛起:

$ bin/pulsar standalone --num-bookies 3
Listening for transport dt_socket at address: 5005

此時(shí),你在 IDE 里可以給代碼隨意打斷點(diǎn),點(diǎn)擊 debug 按鈕后 broker 才會(huì)啟動(dòng),走到斷點(diǎn)處將暫停,我們可以在 IDE 中查看變量、堆棧等信息。

這樣我們就能在 IDE 中同時(shí)調(diào)試 client 端和 broker 端的代碼了。

但是需要注意的是, 進(jìn)行遠(yuǎn)程調(diào)試的源代碼必須和命令行啟動(dòng)的 broker 一致 ,否則會(huì)導(dǎo)致調(diào)試時(shí)行數(shù)對(duì)不上的問(wèn)題。

如果出現(xiàn)源碼對(duì)不上的情況,可以在 pulsar 項(xiàng)目的根目錄用 maven 重新編譯當(dāng)前的源碼:

$ mvn package -DskipTests -Dlicense.skip=true

編譯好的二進(jìn)制包在distribution/server/target中,我們?cè)谛碌陌械?code>bin/pulsar腳本添加遠(yuǎn)程 debug 的參數(shù),然后再次啟動(dòng)即可順利調(diào)試。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 源碼
    +關(guān)注

    關(guān)注

    8

    文章

    632

    瀏覽量

    29111
  • 開(kāi)源項(xiàng)目

    關(guān)注

    0

    文章

    36

    瀏覽量

    7163
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Matepad pro12.2 已上市半個(gè)月,但是還沒(méi)有在開(kāi)源網(wǎng)站看到該項(xiàng)目開(kāi)源信息,違背開(kāi)源精神

    任何該項(xiàng)目開(kāi)源計(jì)劃,違背開(kāi)源精神 按照開(kāi)源社區(qū) licsence和公共庫(kù)開(kāi)源licsence要求,對(duì)應(yīng)的
    發(fā)表于 08-27 17:25

    機(jī)友分享 | 導(dǎo)入機(jī)智云Android開(kāi)源項(xiàng)目的正確姿勢(shì)

    以下文章來(lái)源于小雨編程 ,作者小雨tt“使用機(jī)智云AIoT平臺(tái)支持項(xiàng)目自生成APP源碼,即可輕松解決Android開(kāi)源項(xiàng)目啦,”開(kāi)發(fā)者下載源碼
    發(fā)表于 09-28 10:58

    下載編譯源碼的要點(diǎn)和搭建源碼閱讀環(huán)境的方法

    下載編譯源碼的要點(diǎn)和搭建源碼閱讀環(huán)境的方法。下載編譯源碼,一方面是為了搭建源碼閱讀環(huán)境,另一方面
    發(fā)表于 01-10 06:49

    STM32項(xiàng)目開(kāi)發(fā)中超級(jí)實(shí)用技巧分享

    STM32項(xiàng)目開(kāi)發(fā)中超級(jí)實(shí)用技巧一. 利用軟啟動(dòng)打補(bǔ)丁二. 優(yōu)化等級(jí)盡量選擇不優(yōu)化三. 合理利用開(kāi)關(guān)總中斷所有的熱愛(ài)都要不遺余力,真正喜歡它便給它更高的優(yōu)先級(jí),和更多的時(shí)間吧!關(guān)于STM32其它
    發(fā)表于 01-21 06:22

    2018 年 2 月份 GitHub 最熱門的開(kāi)源項(xiàng)目

    2 月份 GitHub 最熱門的開(kāi)源項(xiàng)目又出爐了,又有哪些新的項(xiàng)目擠進(jìn)熱門榜單了呢,一起來(lái)看看。
    的頭像 發(fā)表于 03-23 08:53 ?4630次閱讀

    基于鴻蒙系統(tǒng)開(kāi)源項(xiàng)目OpenHarmony源碼靜態(tài)分析

    開(kāi)發(fā)者宣布了鴻蒙2.0系統(tǒng)開(kāi)源,源碼托管在國(guó)內(nèi)源碼托管平臺(tái)碼云:https://openharmony.gitee.com/ 我也第一時(shí)間從碼云下載了鴻蒙系統(tǒng)的源代碼,并進(jìn)行了編譯和
    的頭像 發(fā)表于 10-16 10:51 ?9407次閱讀
    基于鴻蒙系統(tǒng)<b class='flag-5'>開(kāi)源</b><b class='flag-5'>項(xiàng)目</b>OpenHarmony<b class='flag-5'>源碼</b>靜態(tài)分析

    分享一個(gè)超級(jí)實(shí)用的源碼閱讀小技巧

    工欲善其事必先利其器; 我發(fā)現(xiàn)函數(shù)調(diào)用圖可以讓我們更加直觀地了解到源碼函數(shù)直接的調(diào)用和層次關(guān)系,提高閱讀源碼的效率 。 1 前言 看源碼的時(shí)候,心血來(lái)潮想弄一下函數(shù)之前的調(diào)用關(guān)系,想起
    的頭像 發(fā)表于 05-29 11:50 ?2004次閱讀
    分享一個(gè)超級(jí)實(shí)用的<b class='flag-5'>源碼</b><b class='flag-5'>閱讀</b>小技巧

    模擬閱讀開(kāi)源分享

    電子發(fā)燒友網(wǎng)站提供《模擬閱讀開(kāi)源分享.zip》資料免費(fèi)下載
    發(fā)表于 11-14 11:21 ?0次下載
    模擬<b class='flag-5'>閱讀</b>器<b class='flag-5'>開(kāi)源</b>分享

    矩陣顯示器的新聞閱讀開(kāi)源項(xiàng)目

    電子發(fā)燒友網(wǎng)站提供《矩陣顯示器的新聞閱讀開(kāi)源項(xiàng)目.zip》資料免費(fèi)下載
    發(fā)表于 02-08 10:46 ?0次下載
    矩陣顯示器<b class='flag-5'>上</b>的新聞<b class='flag-5'>閱讀</b>器<b class='flag-5'>開(kāi)源</b><b class='flag-5'>項(xiàng)目</b>

    閱讀開(kāi)源項(xiàng)目源碼實(shí)用技巧(下)

    這句話其實(shí)是高效 debug 的關(guān)鍵。初看源碼時(shí)「猜」是很重要且很有效的手段,結(jié)合 IDE 的搜索功能,能夠幫我們快速定位關(guān)鍵代碼。
    的頭像 發(fā)表于 04-12 11:37 ?691次閱讀
    <b class='flag-5'>閱讀</b><b class='flag-5'>開(kāi)源</b><b class='flag-5'>項(xiàng)目</b><b class='flag-5'>源碼</b>的<b class='flag-5'>實(shí)用技巧</b>(下)

    Java算法大全源碼開(kāi)源源碼

    Java算法大全源碼開(kāi)源源碼
    發(fā)表于 06-07 14:58 ?1次下載

    Haiku eInk閱讀開(kāi)源分享

    電子發(fā)燒友網(wǎng)站提供《Haiku eInk閱讀開(kāi)源分享.zip》資料免費(fèi)下載
    發(fā)表于 06-15 14:45 ?0次下載
    Haiku eInk<b class='flag-5'>閱讀</b>器<b class='flag-5'>開(kāi)源</b>分享

    Raymond Roussel閱讀機(jī)開(kāi)源分享

    電子發(fā)燒友網(wǎng)站提供《Raymond Roussel閱讀機(jī)開(kāi)源分享.zip》資料免費(fèi)下載
    發(fā)表于 06-15 11:25 ?0次下載
    Raymond Roussel<b class='flag-5'>閱讀</b>機(jī)<b class='flag-5'>開(kāi)源</b>分享

    如何去閱讀源碼,我總結(jié)了18條心法

    在一個(gè)優(yōu)秀的開(kāi)源項(xiàng)目中,設(shè)計(jì)模式處處存在,所以在你開(kāi)始閱讀源碼之前最好先了解一下常見(jiàn)的一些設(shè)計(jì)模式。當(dāng)你了解了一些設(shè)計(jì)模式以后,在源碼中遇到
    的頭像 發(fā)表于 07-17 16:00 ?746次閱讀
    如何去<b class='flag-5'>閱讀</b><b class='flag-5'>源碼</b>,我總結(jié)了18條心法

    浙大博導(dǎo)開(kāi)源飛控planner源碼

    浙大博導(dǎo)開(kāi)源飛控planner源碼
    發(fā)表于 06-12 11:43 ?4次下載