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

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

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

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

jf_78858299 ? 來源:labuladong ? 作者:labuladong ? 2023-04-12 11:37 ? 次閱讀

技巧二、多猜,多搜索,可以在底層庫(標(biāo)準(zhǔn)庫、網(wǎng)絡(luò)框架等)打條件斷點(diǎn)過篩選出關(guān)鍵流程 。

這句話其實(shí)是高效 debug 的關(guān)鍵。初看源碼時(shí)「猜」是很重要且很有效的手段,結(jié)合 IDE 的搜索功能,能夠幫我們快速定位關(guān)鍵代碼。

為什么底層庫適合打斷點(diǎn)呢?因?yàn)槌隹创箜?xiàng)目的代碼很難搞清楚其中的細(xì)節(jié),加上各種異步、多線程的操作,很容易把代碼「跟丟」。如果把斷點(diǎn)打在底層庫的接口/方法上,就可以根據(jù)調(diào)用棧分析調(diào)用過程。

當(dāng)然,底層庫被調(diào)用的次數(shù)比較多,可能出現(xiàn)很多無關(guān)的調(diào)用,所以要結(jié)合條件斷點(diǎn)來過濾掉無關(guān)的調(diào)用。

還是用 Pulsar 舉例,我現(xiàn)在想探究 producer 發(fā)送消息的流程,那么 producer 和 broker 之間的網(wǎng)絡(luò)通信過程就是一個(gè)重要的切入點(diǎn)。

首先發(fā)現(xiàn) Pulsar 的網(wǎng)絡(luò)協(xié)議使用的是 protobuf,而且注意到PulsarApi.proto這個(gè)文件中有一個(gè)BaseCommand定義:

message BaseCommand {
    enum Type {
        CONNECT     = 2;
        SUBSCRIBE   = 4;

        PRODUCER    = 5;

        SEND        = 6;
        SEND_RECEIPT= 7;

        MESSAGE     = 9;
        ACK         = 10;

        PING = 18;
        PONG = 19;
        ...
    }
    
    required Type type = 1;

    
    optional CommandConnect connect          = 2;
    optional CommandConnected connected      = 3;
    ...
}

又發(fā)現(xiàn) Pulsar 底層靠 netty 框架實(shí)現(xiàn)網(wǎng)絡(luò)通信,那么我們可以大膽猜測(cè), 源碼里肯定有一個(gè)大 switch 語句 ,來根據(jù) command 里面的 type 分類處理對(duì)應(yīng)的 command。

所以我們可以全局搜索一下case SEND_RECEIPT ,就找到了PulsarDecoder這個(gè)文件:

圖片

這里會(huì)根據(jù)不同的 command type 調(diào)用不同的 handle 函數(shù),所以可以認(rèn)為這里是 Pulsar 關(guān)鍵功能的入口。

而且注意這是 common 包,也就是說 client 和 broker 都會(huì)依賴這個(gè)包, 所以斷點(diǎn)打在 switch 這里就可以看到 client 和 broker 的網(wǎng)絡(luò)交互 ,每次跳轉(zhuǎn)的 case 就是網(wǎng)絡(luò)命令的交互順序:

圖片

PS:因?yàn)?ping/pong 心跳消息在調(diào)試時(shí)很煩人,所以我們可以通過條件斷點(diǎn)跳過心跳消息。另外,我們需要把 client 里面的各種 timeout 都調(diào)大一些,避免調(diào)試時(shí)出現(xiàn)超時(shí)的錯(cuò)誤。

這樣,啟動(dòng)我們的測(cè)試用例,僅僅通過這一個(gè)斷點(diǎn),就能搞明白 Pulsar 發(fā)消息的流程了:

當(dāng)然,如果你想探究每一步具體做了什么,就跳進(jìn)具體的 handle 函數(shù)里一步步調(diào)試即可。

技巧三、利用各種可視化工具 。

你比如,上面說的網(wǎng)絡(luò)通信過程,我們知道了 produce 一條消息的流程,但每條 protobuf 數(shù)據(jù)包里面到底存了什么信息呢?

關(guān)于這個(gè)問題,社區(qū)有大佬寫了一個(gè) lua 腳本, 可以用 wireshark 解析 Pulsar 協(xié)議格式 ,具體說明在這里:

https://github.com/apache/pulsar/tree/master/wireshark

按照說明配置并啟動(dòng) wireshark 之后,可以使用如下過濾命令過濾掉無關(guān)的數(shù)據(jù)包:

tcp.port eq 6650 and pulsar and protobuf.field.name ne "ping" and protobuf.field.name ne "pong"

接下來啟動(dòng) standalone,通過 Java client 發(fā)送一條消息,就可以在 wireshark 抓到 10 個(gè)數(shù)據(jù)包,和剛才通過 debug 得到的流程是一樣的:

同時(shí),我們還可以查看每個(gè)包的具體數(shù)據(jù),比如PARTITITONED_METADATA命令就是在查詢 topic 對(duì)應(yīng)的 partition 有多少,因?yàn)檫@里是個(gè)非分區(qū)的 topic,所以PARTITITONED_METADATA_RESPONSE返回了 0:

再比如LOOKUP命令用來查詢 broker 的 URL,因?yàn)槲覀儐?dòng)的 standalone 只有一個(gè) broker,所以LOOKUP_RESPONSE返回的只有一個(gè) URL:

在真實(shí)的使用場(chǎng)景中肯定有多個(gè) broker,所以這個(gè)LOOKUP_RESPONSE應(yīng)該會(huì)返回多個(gè) broker URL。

最后看一下真正發(fā)送消息的SEND命令里面具體有什么數(shù)據(jù):

圖片

可以看到這里面有 producer_name, sequence_id 等數(shù)據(jù),每條消息的 sequence_id 單調(diào)遞增,用來防止由于網(wǎng)絡(luò)重傳導(dǎo)致的消息重復(fù),和 tcp 里面的 seq 差不多的原理。

另外可以看到真正的消息數(shù)據(jù)放在數(shù)據(jù)包的最后,通過一個(gè)字段記錄數(shù)據(jù)的長(zhǎng)度。

具體的玩法可以有很多,我這里就不一一列舉了,其實(shí)除了 wireshark 分析 Pulsar 的網(wǎng)絡(luò)通信, 還可以使用 zookeeper 的可視化工具查看 Pulsar 的元數(shù)據(jù) 。

比如 prettyZoo 就是一款對(duì) zookeeper 可視化的開源工具,那么我就可以在 Pulsar standalone 啟動(dòng)之后(會(huì)自動(dòng)啟動(dòng) zookeeper),讓 prettyZoo 連接到 zookeeper 的端口,很直觀地查看 zookeeper 里面的節(jié)點(diǎn)數(shù)據(jù):

圖片

這里面很多數(shù)據(jù)可能不好理解,但我們手上有源碼, 這些路徑大概率是以字符串常量的形式表現(xiàn)的,那全局搜索就行了

比如這個(gè)producer-name的路徑,我們搜一下就定位出來了:

圖片

簡(jiǎn)單瀏覽一下源碼,原來是借助 zookeeper 生成全局唯一的生產(chǎn)者名字。

最后

本文也夠長(zhǎng)了,主要介紹了一些閱讀開源項(xiàng)目源碼的實(shí)用技巧,總結(jié)來說就是: 善于找資源,善于用工具

雖然本文是以 Pulsar 為例,但這些技巧都是通用的,可以運(yùn)用到任何比較成熟的開源項(xiàng)目上去。

如果你也有什么經(jīng)驗(yàn)分享,可以留言告訴我,掌握技巧只是漫漫長(zhǎng)路的第一步,讓我們共同在開源社區(qū)里成長(zhǎng)進(jìn)步。

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

    關(guān)注

    0

    文章

    334

    瀏覽量

    46586
  • 開源
    +關(guān)注

    關(guān)注

    3

    文章

    3185

    瀏覽量

    42241
  • DEBUG
    +關(guān)注

    關(guān)注

    3

    文章

    89

    瀏覽量

    19808
收藏 人收藏

    評(píng)論

    相關(guān)推薦

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

    Matepad pro12.2 已上市半個(gè)月,本人自己也購買了同款12+256的pad,想要同步學(xué)習(xí)這款pad的一些體驗(yàn)還不錯(cuò)的功能點(diǎn),但是目前為止還沒有在開源網(wǎng)站看到該項(xiàng)目開源
    發(fā)表于 08-27 17:25

    關(guān)于Linux的源代碼閱讀問題

    ,linux開源,應(yīng)該所有庫函數(shù)都可以進(jìn)去的了。2.在Linux項(xiàng)目,沒有像MDK那樣做一個(gè)項(xiàng)目,然后規(guī)范文件分類嗎?否則,項(xiàng)目一大,文
    發(fā)表于 11-21 11:04

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

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

    【HiSpark系列】潤(rùn)和 HiHope 社區(qū) 開源項(xiàng)目集合

    Demo App的源碼https://gitee.com/hihopeorg/GOpenSource_AppKit目前相關(guān)的開源代碼都放在了這里,感興趣的可以看一
    發(fā)表于 10-22 09:52

    C語言開源項(xiàng)目

    值得學(xué)習(xí)的C語言開源項(xiàng)目- 1. WebbenchWebbench是一個(gè)在linux使用的非常簡(jiǎn)單的網(wǎng)站壓測(cè)工具。它使用fork()模擬多個(gè)客戶端同時(shí)訪問我們?cè)O(shè)定的URL,測(cè)試網(wǎng)站在壓力下工
    發(fā)表于 08-20 06:15

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

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

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

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

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

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

    優(yōu)秀的 Verilog/FPGA開源項(xiàng)目介紹(一)

    的參考價(jià)值。 這里再介紹一開源協(xié)議的區(qū)別,方便大家在閱讀使用這些開源項(xiàng)目時(shí)尊重規(guī)則。 詳情查看:https://suisuisi.blog
    的頭像 發(fā)表于 10-11 15:31 ?9115次閱讀
    優(yōu)秀的 Verilog/FPGA<b class='flag-5'>開源</b><b class='flag-5'>項(xiàng)目</b>介紹(一)

    模擬閱讀開源分享

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

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

    電子發(fā)燒友網(wǎng)站提供《矩陣顯示器上的新聞閱讀開源項(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'>項(xiàng)目</b>

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

    本文分享一在使用或者學(xué)習(xí)開源項(xiàng)目源碼的過程中的一些經(jīng)驗(yàn)技巧。 因?yàn)槲易罱谘芯?Apache Pulsar 這款消息隊(duì)列,所以就以這個(gè)項(xiàng)目
    的頭像 發(fā)表于 04-12 11:34 ?1072次閱讀
    <b class='flag-5'>閱讀</b><b class='flag-5'>開源</b><b class='flag-5'>項(xiàng)目</b><b class='flag-5'>源碼</b>的<b class='flag-5'>實(shí)用技巧</b>(上)

    Java算法大全源碼開源源碼

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

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

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

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

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