學習開源項目的若干建議
隨著國內開源社區和項目的不斷發展,學習、應用、貢獻開源項目的開發人員越來越多。最近,研究過多個開源項目(包括KVM/QEMU、libvirt、OpenStack、Ceph、Zabbix等)的業內專家章宇在其博客中分享了學習開源項目的若干建議,值得讀者借鑒。
章宇認為,學習開源項目,可以劃分為五個層次,分別是:
1、了解項目的基本概念、基本用途、邏輯結構、基本原理、產生背景、應用場景等基本知識。這個層次的基本定位其實就是“科普”。如果對于一個項目只需要有些基本了解,且短期內并不需要上手進行實際技術工作,則學習到這個層次也就可以先應付一下了。
2、掌握項目的基本安裝流程和使用方法。這個層次的基本定位是“入門”,以便對這個項目獲得直觀認識,對其安裝和使用獲得親身體驗。如果只是需要以as-is方式使用這個項目,則初步學習到這個層次即可。
3、了解代碼的組織,找到各個主要邏輯/功能模塊與代碼文件之間的對應關系,通過代碼分析走通幾個關鍵的、有代表性的執行流程。這個層次的基本定位是“深入”,開始理解這個項目的實際實現,能夠真正將項目的功能、工作原理和代碼實現對應起來,獲得對這個項目工作過程的直觀認識。這個層次是學習開源項目代碼的真正開始。如果希望基于這一項目進行應用開發,或者針對與這一項目密切相關的其他項目進行工作時,則對項目本身的代碼進行這一層次的理解,會很有幫助。
4、了解該項目所有代碼模塊、程序文件的作用,走通所有主要執行流程。這個層次的基本定位是“掌握”,能夠比較全面、系統地理解這個項目的設計和實現,并且熟悉項目各個部分的代碼。如果希望對項目進行深度定制修改,或者對社區有所貢獻,則應當以達到這個層次作為目標。
5、鉆研、領悟該項目的各種設計思想與代碼實現細節。這個層次的基本定位是“精通”,精益求精,學無止境。這是大神們追求的境界。如果希望成為項目社區的重要貢獻者乃至核心貢獻者,則應當以這個層次作為努力的目標。
學習開源項目,必須要掌握一些基礎知識,章宇指出了三點:
- 該項目涉及的技術領域的背景知識。舉例而言,分析Linux Kenrel,則應該了解操作系統原理;學習OpenStack,則應該知道什么是云計算。如果沒有這些背景知識作為基礎,上來就死磕源代碼,只能是事倍功半。
- 該項目開發使用的語言及其各種開發調試工具。
- 英語。很遺憾,目前為止真正流行的開源項目大部分不是起源于國內。因此,除了學習個別極其流行、文檔完備的項目之外,大家還是需要自行搜集閱讀英文資料參考。學好英語很重要。
有了學習的目標和基礎知識,接下來就是學習的思路和過程,章宇總結了一套由表及里、逐漸深入的學習方法。
在剛開始接觸一個項目的時候,我們看到的其實就是一個黑盒子。根據文檔,我們一定會發現盒子上具有若干對外接口。通常而言,這些接口可以被分為三類: 1、配置接口:用于對盒子的工作模式、基本參數、擴展插件等等重要特性進行配置。這些配置往往是在盒子啟動前一次性配好。在盒子的工作過程中,這些配置或者不變,或者只在少數的情況下發生改變。 2、控制接口:用于在盒子的工作過程中,對于一些重要的行為進行操縱。這是盒子的管理員對盒子進行控制命令注入和狀態信息讀取的通路。 3、數據接口:用于盒子在工作過程中讀取外部數據,并在內部處理完成后向外輸出數據。這是盒子的用戶真正關心的數據通路。 因此,在分析一個開源項目的代碼時,可以圍繞重要的配置、控制、數據接口展開分析工作,特別應該注意理解一個關鍵的接口背后隱藏的操作流程。例如,針對數據接口,至少應當走通一條完整的數據輸入輸出流程,也即在代碼中找到數據從輸入接口進入盒子后,經過各種處理、轉發步驟,最終從輸出接口被傳輸出去的整個執行過程。一旦走通了這樣一條流程,則可以將與數據處理相關的各個主要模塊、主要步驟貫穿起來,并將邏輯模塊圖上和文檔中的抽象概念對應到代碼實現之中,可以有效推進對于項目的深入理解。 在實踐這一思路的過程中,筆者建議可以優先從控制接口和數據接口中各自選擇一二重要者進行背后的執行流程詳細分析,力爭找到其中每一步的函數調用及數據傳遞關系(對于一些系統、應用庫提供的底層函數可以先行跳過以節省時間)。這一工作完成之后,則第三層次的學習目標即可初步達成。 配置接口在不同的項目中的重要程度不同。對于一些架構極為靈活、配置空間甚大的項目(如OpenStack的Ceilometer),則可以適當多花些時間加以研究,否則簡單了解即可。
|
作者以“OpenStack Cinder”為例,講述了如何學習開源項目:
1、首先,想對Cinder進行分析,一定要了解若干相關的基礎知識。什么是云計算?什么是塊存儲?什么是OpenStack?Cinder在OpenStack里的作用?等等等等。如果對這些東西沒有概念,則后續學習是很難開展下去的。
2、在此基礎上,如果有條件,則***能夠親自部署和實際操作一下Cinder(包括必要的其他OpenStack組件),以便對Cinder獲得一個直觀的認識和體驗,為后續分析提供一些參考。此處假定Cinder使用的后端是Ceph,而OpenStack上運行的虛擬機是KVM。
3、然后,應該從概念上對我們要分析的系統的邏輯框架有個理解。從總體的范疇上講,應該了解Horizon和Nova各自的邏輯模塊結構,以及它們和Cinder的協同工作方式、關系。這部分與Cinder的控制接口及執行路徑分析密切相關。此外,還應該了解Cinder和KVM/QEMU、Ceph之間的相互關系。這對于真正理解Cinder很有幫助。從Cinder自身而言,應該了解其內部邏輯模塊構成、各自的功能、相互間的控制、數據連接關系等。
4、在完成上述準備之后,則可以開始對Cinder的代碼進行分析了。如前所述,應該考慮在控制接口和數據接口中各自選擇一兩個關鍵的、有代表性的加以分析。至于配置接口,假定其實現了某一配置即可,暫時不需要過多花費時間。Cinder的核心功能其實是OpenStack上的volume管理。至少在Cinder+Ceph方案中,Cinder自身并不在數據傳輸關鍵路徑上。因此,控制接口的分析就是Cinder源代碼分析的重中之重。就入手階段而言,則有兩個接口及其對應執行流程可以作為Cinder分析的起點,即volume的create和attach操作。如果能夠徹底打通這兩個操作的執行流程(至少要看到Cinder與Ceph通過librbd交互的層面),則對于真正理解Cinder的功能與實現大有幫助。雖然基于KVM的虛擬機在通過QEMU訪問Cinder創建的、Ceph提供的volume時并不通過Cinder,也即,這一部分的源代碼其實已經超出了Cinder源代碼學習的范疇,但是,如果希望真正徹底地理解Cinder,則對于這一部分知識還是應該有所涉獵,至少應該有概念上的了解。
除此之外,作者還提供了一些建議,比如過好筆記、不要過分糾纏于細節等,完整的內容可以查章宇的博客。InfoQ的讀者對學習開源項目有何心得,歡迎發表自己的看法。