工程師如何選擇開源軟件?

語言: CN / TW / HK

編者按本文節選自《工程師如何對待開源》,作者譚中意是星策開源社區發起人、中國開源推進聯盟副祕書長,同時也是在知名科技企業從事開源相關工作超過 20 年的工程師,親身經歷或者親眼目睹很多工程師開源領域的優秀實踐,同時也看到了很多 Bad Cases工程師如何對待開源》一文凝聚作者諸多心得和體會除了本文所呈現的“工程師如何選擇開源軟件的內容之外,還着重闡述了“工程師如何定製和維護開源軟件”“工程師個人成長如何利用開源兩個話題。譚中意説:“希望能幫助工程師更好成長。 

作者:星策開源社區發起人、中國開源推進聯盟副祕書長 譚中意

作為技術工程師,工作任務就是用技術手段支持和實現公司所關注的商業目標。 實際工作中,主動或者被動使用和維護大量開源軟件。 據統計,每個工程師在企業內部進行研發和運維等工作的時候,每年會接觸到上千款開源軟件, 如果是以Java或JavaSciprt 為主要程序開發語言的工程師,則接觸到的開源軟件數量更多,在萬級別甚至十萬級別。 數據來源:《2020 State of the Software Supply Chain》由 Sonatype 發佈

那麼如何選擇開源軟件? 這麼多開源軟件中,如何根據個人需求和業務需要來選擇合適的開源項目進行投入

首先要明確對開源軟件的態度,在現階段開對開源軟件的使用。不過,使用開源軟件會面臨各種各樣的風險,包括開源合規、安全、效率問題。 簡化為一句:在企業內部高效、安全、合規使用開源軟件,需要遵守該企業對開源軟件的內部規定,包括如何引入和如何維護

回到具體如何選擇特定的開源軟件的問題上,有如下幾個緯度可以進行參考。

  • 根據需求
  • 根據技術發展趨勢
  • 根據軟件採納週期的不同階段
  • 根據開源軟件的成熟度情況
  • 根據項目的質量指標
  • 根據項目的治理模式

一、根據需求來選擇開源軟件

選擇開源軟件,首先要明確需求,即選擇這個開源軟件的目的究竟是什麼是用來進行個人學習的; 還是用來滿足 to B客户的需求的;是用來滿足內部服務開發的需求的。 因為不同的目的,選擇開源軟件的導向完全不一樣。(注意:後兩個場景需要先考慮企業開源合規的需求,參考各個企業內部開源合規要求

進行個人學習

先説説選擇開源軟件來進行個人學習,那麼要看學習的具體目的究竟是什麼。 是想學習一種比較流行的技術來完善個人的技術知識結構擴大個人技術視野;還是想看看相應的開源技術項目的具體實現,來作為內部項目技術開發的參考;還是想為了下一份工作有針對性進行技術準備。

針對前者,顯然是什麼技術最流行選什麼,自己缺什麼選什麼;針對第二種目的,一般是對該技術領域的知名開源軟件或創新性軟件針對性地進行選擇,即某個特性是我當前需要的,或者是我當前項目實現不好的,我需要看看別人是如何實現的。最後一種,顯然是按照下一份工作的職位需要和技術棧要求進行準備,並根據技術棧要求的門檻高低進行選擇。

但是注意,從個人需求出發選擇開源軟件,一般都需要寫個小項目練練手,比如一個 Demo 程序或者一個測試服務,因為不用考慮後續的長期維護,所以儘可以按照個人的想法和個人研發習慣進行各種練習,不用遵循企業內部的開發流程和質量要求,也不用考慮該開源軟件的穩定性和社區成熟度等情況,只需要盡情學習和參考代碼就好了。

滿足 to B 客户的需求

選擇開源軟件進行研發的軟件是需要提供給客户的,往往可能是以私有云的方式進行交付。基於此類需求來選擇開源軟件,注意好平衡,即要平衡好客户的需求和企業自身技術規劃或產品的長期規劃需要。

以私有云方式進入客户的 IDC 環境,是需要跟客户開發和運行環境的上下游項目進行集成的。這時候要看客户的需要,可能某些客户對開源軟件有特定的要求,例如要求使用 HDFS 而且是某個特定版本。客户之所以會指定軟件名字和指定版本,可能是因為當前比較熟悉這個版本,也有可能是因為之前其他軟硬件供應商提供的軟件和版本,指定的目的是方便集成和後續的使用與維護。

如果這種需求是符合企業項目或者產品的長期發展需求的,則是可以完全滿足的。如果甲方非常強勢,除了滿足他的要求之外沒有別的辦法,那就選擇客户所指定的軟件和版本好了。

但如果跟自身項目或產品的長期發展需求不一致,而且具體項目或者版本是可以跟甲方進行協商的,那麼需要跟客户協商出一個雙方都能接受的結果,即選擇特定的開源軟件和版本既要做到客户滿意並買單,又要做到自身的交付成本可控,還要做到符合自身項目或者產品的長期發展需要。

例如客户使用 Java 的某個老版本,但是企業的 to B 交付的軟件要求使用 Java 的較高版本。那麼需要跟客户協商,要麼切換到企業希望的版本上,還需要幫助客户完成已有系統的升級工作;要麼只能降低自身軟件的 Java 版本需求,可能還需要對某些自身代碼進行修改,還可能對軟件中的某些依賴組件進行修改。這個場景下是帶有很多客觀約束條件下的選擇,是需要跟客户,自身的產品經理和架構師一起協商的。

滿足內部服務需求

如果場景是為了滿足內部服務的需求,即選擇開源軟件來搭建的服務是給內部業務或者最終用户來使用的,常見於國內各大互聯網公司的互聯網服務系統和各種手機上的 App。這時候項目的開發和維護方有較大的自主權,跟 to B的交付業務完全不一樣。此時選擇開源軟件,就一定要綜合考慮開發和維護成本,還要考慮使用該服務的業務所處的階段。

1如果提供的服務是給創新業務使用的,創新業務一般都是試錯業務,隨時需要根據市場情況的變化和當前執行的狀態進行調整,很可能三個月後這個項目沒了,即被取消了。這種情況下 “糙快猛” 的開發方式是比較合適的,不用太多考慮系統的可維護性和可擴展性,就用研發團隊最熟悉的軟件技術棧,然後用底層技術支撐團隊比如基礎架構團隊提供的成熟而且經過驗證後的底層基礎技術平台就可以,最重要是儘快把系統搭建出來,然後隨着產品進行快速的迭代。

這個時候需要儘量降低現有研發運維團隊的學習成本和開發成本,不用太多考慮可維護成本,因為需要糙快猛的把系統堆出來,驗證產品需求和商業模式是最重要的,時間最重要。如果發現有市場機會,就快速跟進,站穩腳跟之後可以採用省時間但是費資源的方式(俗稱 “堆機器”)來進行擴展,或者採用 “邊開飛機邊換引擎” 的模式進行重寫都是比較划算的。對於處於創業階段的企業或者項目來説,速度勝過一切。

2如果選擇開源軟件搭建出來的計算機軟件系統或者服務需要長期維護,比如是給公司內成熟業務使用的,或者是針對公司內成熟平台的缺點進行系統升級並要替代原有產品的,那麼在滿足業務需求的前提下,考慮系統的可維護性變成最重要的事情。

選擇對應的開源軟件,它是否成熟,是否穩定;二次開發是否友好;運維成本是否比較合算即比較省機器和帶寬;運維操作是否方便,例如常見的擴容和縮容操作是否可以高效、自動、無損的完成;Upstream 到上游開源社區是否容易等等,這些都成為需要重點考慮的事情。這種情況下,開發一個系統的成本,可能只佔整個系統生命週期內的成本的 1/10 不到。所以在滿足需求的前提下,重點考慮可維護性。

二、 根據技術發展趨勢來選擇開源軟件

如上圖所示,現代計算機軟件或者服務的研發,是一個不斷運行的循環和迭代過程。從市場分析開始,然後進入到創意階段,再到編碼階段,最後到上線階段完成應用的部署和生效,上線之後根據得到的數據反饋,繼續進行分析。

這個循環迭代的過程,顯然對於一個身處行業競爭激烈的企業來説,迭代的速度越快越好,同時也需要具備快速彈性、低成本伸縮的能力,即產品方向對了,那麼趕緊進行系統擴容,承接快速增長的流量,做到快速增長;如果產品方向不對,需要趕緊縮容,把相關硬件和人力資源節省出來,投入到新的試錯方向上去。身處同一個行業內的企業,如果企業 A 能以更低的成本,更快的速度進行各種產品和策略的迭代,顯然它比迭代速度慢,成本高的企業 B 更具有競爭優勢。

現在的開源軟件數量非常多,幾乎每一個分類下面都有很多的開源項目。針對某一個具體的需求,如何進行選擇?一個建議是根據技術趨勢進行選擇。即現在的計算機系統迭代的方式是 Agile(敏捷) + Scale(擴展)。

顯然,能夠支持計算機系統進行快速迭代,並能夠很方便進行低成本彈性伸縮的開源軟件值得進行長期投入。而對一個新的開源軟件的學習和使用,學習者是希望該軟件的學習門檻越低越好。一個流行的開源軟件,內部實現可以儘可能複雜,但是對於用户來説一定是需要用户友好的。不然即使創新度再好,易用性不好,只有極客才能學習和掌握,創新的鴻溝很難跨越。

例如 Docker 的出現之後,以極快的速度風靡全球之所有非常多的工程師喜歡 Docker就是因為 Docker 的特性——在傳統的容器系統之上增加了新特性,包括把應用程序和底層依賴庫封裝為一個容器鏡像,容器鏡像有版本,而且可以通過集中的鏡像倉庫進行存儲和大批量分發。

Docker 首先解決了長期困擾工程師的開發、測試、上線環境標準化的問題,能夠支持開發者進行快速的迭代。同時使用了統一的鏡像倉庫來進行鏡像的分發,而且底層採用了輕量級虛擬機即容器的技術,可以非常快被拉起,所以採用 Docker 的系統可以很方便進行彈性擴展。同時,因為把應用 App 封裝在一個鏡像裏面,可以在邏輯上根據 Domain Model的設計原則進行更好抽象和複用。

顯然,這樣的技術值得每一個開發計算機系統的工程師學習和掌握。因為他能帶來極大的方便。

相反,在 Docker 產生之前,雖然 Control Group(簡稱 cgroup) + Namespace 的技術早就已經出現,並早就集成在 Linux 內核中,Google 的 borg 相關的論文早就已經發表,但是一般的技術研發團隊不是很容易就能駕馭容器並把容器系統在公司內部大規模進行部署的。

印象中 borg 論文出現後,國內只有 BAT 級別的互聯網公司,才有一小撮精英研發團隊來研發和使用容器管理系統,例如百度負責 Matrix 系統研發的團隊,阿里負責 Pounch 系統研發的團隊,騰訊也有一個小團隊負責容器系統的研究。

但是除了那一小部分團隊,更多的工程師因為學習難度較大而沒有把容器大批量地用起來。而Docker這種技術,非常好順應了敏捷和彈性擴展的技術趨勢,而且提供了非常好的用户易用性,一出場就被非常多的工程師迅速使用,而且成為市場的默認標準。

這些順應潮流的開源軟件是值得選擇和投入的。

另外一個例子是 Spark,Spark 的出現解決了 MapReduce 在分佈式計算過程中因為需要頻繁進行 IO 操作導致的性能比較低下的問題,同時在易用性上有較大的提升,所以才取代了 MapReduce 在分佈式計算領域內的主流地位。

三、根據開源軟件採納週期的不同階段進行選擇

軟件作為智力活動的產物,有它自己的生命週期,一般用軟件的技術採納曲線表示。

開源軟件也是軟件的一種,也都遵循軟件的技術採納規律。如下圖所示

一個開源軟件從創建到衰亡一般會經過 5 個階段。 從創新期(Innovators,佔比 2.5%),到早期採納期(Early Adopters,佔比 13.5%),然後跨越鴻溝(chasm),進入到早期大眾期(Early Majority,佔比 34%),再進入後期大眾期(Late Majority,佔比 34%),最後進入衰退期(Laggards,佔比 16%)。

絕大部分的開源創新項目,沒能成功的跨域鴻溝,即從早期採納階段進入到早期大眾階段,就消亡了。 所以,如果是選擇一個需要長期使用並維護的開源項目,選擇處於早期大眾或者後期大眾狀態的項目是比較理智和科學的。

當然如果只是個人想學習一個新的東西,可以看看處於創新者狀態的開源項目,或者看看處於 “早期採納者” 狀態的項目。

注意不管是從長期研發系統的角度,還是從個人學習的角度,都不要再去看處於衰退期(Laggards)的項目了。 例如現階段即 2022 年,是不用再去選擇 Mesos,Docker Swarm 之類的項目了。自從 Kubernetes 成為容器調度技術分類的默認標準,這兩個項目就已經處於衰退期,他們的母公司都已經放棄了。這個階段如果還投入較多精力來開發和維護,除非真的是非常強勢的甲方要求,把錢砸在工程師面前得他們不得不用。

同學們可能會問,從哪裏可以看到這些技術採納度曲線?InfoQgartnerthoughtworks 每年都會更新他們各自的技術採納度曲線並公佈出來,可以 根據這些曲線,再結合一些業內的經驗,得出自己的判斷。

從2022 年 InfoQ 對 BigData 領域各種流行技術的判斷來看,Hudi、Clickhouse、Delta Lake 等開源軟件還處於創新者的階段,即在工業界採納還比較少,想學習新項目的同學可以重點關注。但是現在這些開源軟件還不適合應用在需要長期維護的成熟應用場景裏面。

注意這些知名科技媒體的技術採納曲線是每年都在更新的,在進行參考的時候別忘了注意一下發表的時間。

2022 年 InfoQ 對 BigData 領域各種流行技術的判斷

四、根據開源軟件的成熟度情況選擇開源軟件

還有一點,即根據開源軟件本身的成熟度來選擇開源。 即從這個開源軟件是否定期發佈,是否處於一個多方維護的狀態(即使一個公司的戰略發生了變化不再繼續維護了,還有其他的公司在長期支持),是否文檔比較齊全等多個維度來進行成熟度的評估。

對於開源軟件的成熟度模型,開源社區有很多度量開源項目的成熟度模型,其中 Apache 開源軟件基金會的項目成熟度模型是比較有名的把一個開源項目的評估緯度,分為 7 個維度:

  • Code(代碼)
  • License and Copyright(軟件許可證和版權)
  • Release(發佈)
  • Quality(質量)
  • Community(社區)
  • Consensus Building(共識共建)
  • Independence(獨立性)

每個緯度又有幾個考察項。例如針對 Independence(獨立性),又有兩個考察項,其一是看這個項目是否獨立於任何公司或者組織的影響,其二是看貢獻者在社區內活動是代表他們個人,還是作為公司或者組織的代表出現在社區並進行活動的。

Apache 基金會 Top Level 的項目即頂級項目,在畢業階段都會從這些維度進行綜合的判斷。只有各方面都達標的項目,才會被允許從 Apache 基金會的孵化狀態中畢業而成為成為 Top Level 的項目。這也是逼着個人比較喜歡 Apache 頂級項目的原因。

另外,OpenSSF 項目的 Criticality 評分(參見 http://github.com/ossf/criticality_score)也是一個不錯的參考指標,它會度量一個項目的社區貢獻者數量、提交頻度、發版頻度、被依賴的數量等指標,來判斷一個開源軟件在開源生態中的重要程度。這裏就不詳細展開了,有興趣的同學可以參考它的資料,個人認為是一個值得參考的方向,但是這個評分還處於早期階段,距離理想狀態還比較遠。

五、根據項目的質量指標來進行選擇

很明顯,有些開源軟件的代碼質量是比其他開源軟件的質量好。 有的時候需要從項目的質量情況來選擇開源軟件。

這個時候,我們需要查看一些被業內廣泛證明比較有效的指標。

其中 MTTU 是被知名開源供應鏈軟件供應商 SonaType 所推薦的指標。 

MTTU(Mean Time to Update):即開源軟件更新它依賴庫的版本的平均時間。舉個例子來説,某開源軟件 A 依賴於開源庫 B,假設 A 的當前版本是 1.0,依賴 B 的版本是 1.1。某天開源庫 B 的版本從 1.1 升級到了 1.2,然後一段時間之後,開源軟件 A 也發佈了新版本 1.1,其中把對 B 的依賴版本從 1.1 升級到了 1.2。這個時間間隔,即從開源版本 B 的版本升級到 1.2 的時間點距離開源軟件 A 的新版本 1.1 的發佈時間,稱之為 Time to Update

這個時間反映出來的是開源軟件 A 的研發團隊,根據依賴庫的更新週期,同步更新它的依賴版本的能力。Mean Time to Update 是指這個軟件的平均升級時間。數值越低表明質量越好,表明該軟件的負責人在很快速升級各種依賴庫的版本,在及時修復各種依賴庫引起的安全漏洞問題。

據 SonaType 的統計,業內開源軟件的更新升級時間 MTTU 越來越短。在 Maven 中心倉庫上的 Java 類開源軟件,2011 年平均的 MTTU371天2014年平均的MTTU為302天,2018 年平均的 MTTU 是 158 天,而 2021 年平均的 MTTU 時間是 28 天。能看出來,隨着開源軟件庫更新頻率的加快,使用它們的軟件也加快了更新版本的速度,MTTU 相對 10 年前,時間縮短到原來的 10/1 以下。

當然 MTTU 只項目質量的一個間接緯度。 歷史上是否爆出重要高危安全漏洞,修復響應是否快速及時等等也是開源項目質量評價的重要維度。

某些大廠的安全部門,會不斷評估開源軟件的安全情況,把某些屢屢發生高危安全漏洞,但是修復不及時的開源軟件設定為不安全軟件,列入到內部的開源軟件黑名單中對內公示,並要求各個業務研發團隊不再使用這些軟件如果實在因為研發和人力問題不能遷移到新的軟件系統也需要把這些老服務遷移到一個相對封閉的網絡環境中,減少風險可能造成的損失。這個時候,顯然應該需要遵守公司的安全規定,不再使用黑名單上的開源軟件。

六、從開源軟件所屬於的開源社區治理模式角度來考慮

還有一個維度,即從開源項目的社區治理模式來考慮,適用於需要長期進行開發和維護的項目。

社區治理模式(Governance Model)主要是指該項目或者社區是如何做決定的以及由誰來做決定。 具體表現為: 是所有人都可以做貢獻嗎還是少數幾個? 決定是通過投票的方式產生的,還是通過權威?計劃和討論是否可見?

常見的開源社區和開源項目的治理模式有如下三種:

單一公司主導:特點是軟件的設計、開發和發佈都由一個公司來控制,也不接受外部貢獻。開發計劃和版本計劃不對外公開,相關討論也不對外公開,版本發佈時候才對外公開源碼。例如 Google 的Android 系統。

獨裁者主導(有個專有名詞 “Benevolent Dictatorship”,翻譯為 “仁慈的獨裁者”):特點是由一個人來控制項目的發展,他有強大的影響力和領導力,一般都是該項目的創始人。例如 Linux Kernel 由 Linus Torvalds 來負責,Python 之前由 Guido Van Rossum 來主導。

董事會主導:特點是有一撥人構成項目的董事會來決定項目的重大事項。例如 Apache 軟件基金會的項目由該項目的 PMC 決定,CNCF 的基金會的決策是 CNCF 董事會來負責(很多技術決定授權給了 CNCF 董事會下的技術監督委員會)。

個人意見和經驗,根據該開源軟件背後的開源社區的治理方式來進行選擇優先級的排序如下:

優先選擇 Apache 畢業項目因為這些項目的知識產權情況清晰,而且至少有三方在長期維護

次優選擇 Linux 基金會等其他開源基金會的重點項目因為 Linux 基金會的運營能力很強,每個重點項目後面往往都有一個或者多個大公司在支持

小心選擇一個公司主導的開源項目因為該企業的開源戰略隨時可能會調整,很有可能不再持續支持該項目,例如 Facebook 就是一個棄坑很多的公司

儘量不選擇個人開源的項目個人開源更加隨意,風險尤其高,但是不排除某些已經有很高知名度,並且跑出長期維護模式的項目,例如知名開源作者尤雨溪(Evan You)所負責的 Vue.js 開源軟件。

這是個人推薦的選擇同類開源軟件項目的優先級順序,僅僅代表個人觀點,歡迎討論。

 

本文已刊發於開源精選集《開源觀止》第 2 期,更多精彩內容,請點擊下載:

http://oscimg.oschina.net/public_shard/opensource-guanzhi-20220707.pdf