Node.js與io.js那些事兒
原文 http://www.infoq.com/cn/articles/node-js-and-io-js
去年12月,多位重量級Node.js開發者不滿Joyent對Node.js的管理,自立門戶創建了io.js。io.js的發展速度非常快,先是于 2015年1月份發布了1.0版本,并且很快就達到了2.0版本,社區非常活躍。而最近io.js社區又宣布,這兩個項目將合并到Node基金會下,并暫 時由“Node.js和io.js核心技術團隊聯合監督”運營。本文將聊一聊Node.js項目的一些歷史情況,與io.js項目之間的恩怨糾葛,他們將 來的發展去向。希望能從歷史的層面去了解這個開源項目在運營模式上是如何演變和發展的。
Node.js項目的由來
自從JavaScript被Brendan Eich創造出來后,除了應用在瀏覽器中作為重要的補充外,人類從來就沒有放棄過將JavaScript應用到服務端的想法。這些努力從 livewired項目(1994年12月)開始,就從來沒有停止過。如果你不知道livewired,那應該知道ASP中可以使用JScript語言 (1996年),或者Rhino。但直到2009年,這些服務端JavaScript技術與同樣應用在服務端的Java、PHP相比,顯得相對失色。
談到Node.js的由來,不可避免要聊到它的創始人Ryan Dahl。在2009年時,服務端JavaScript迎來了它的拐點,因為Ryan Dahl帶來了Node.js,在那之后Node.js將服務端JavaScript帶入了新的境地,大量的JavaScript在GitHub上被貢獻 出來,大量的JavaScript模塊出現,出現了真正的繁榮。
Node.js不是憑空出現的項目,也不是某個Web前端工程師為了完成將JavaScript應用到服務端的理想而在實驗室里搗鼓出來的。它的 出現主要歸功于Ryan Dahl歷時多年的研究,以及一個恰到好處的節點。2008年V8隨著Chrome瀏覽器的出世,JavaScript腳本語言的執行效率得到質的提升, 這給Ryan Dahl帶來新的啟示,他原本的研究工作與V8之間碰撞出火花,于是帶來了一個基于事件的高性能Web服務器。
上圖為Node.js創始人Ryan Dahl。
Ryan Dahl的經歷比較奇特,他并非科班出身的開發者,在2004年的時候他還在紐約的羅徹斯特大學數學系讀博士,期間有研究一些分形、分類以及p-adic 分析,這些都跟開源和編程沒啥關系。2006年,也許是厭倦了讀博的無聊,他產生了『世界那么大,我想去看看』的念頭,做出了退學的決定,然后一個人來到 智利的Valparaiso小鎮。那時候他尚不知道找一個什么樣的工作來糊口,期間他曾熬夜做了一些不切實際的研究,如如何通過云進行通信。下面是這個階 段他產出的中間產物,與后來蘋果發布的iCloud似乎有那么點相似。
從那起,Ryan Dahl不知道是否因為生活的關系,他開始學習網站開發了,走上了碼農的道路。那時候Ruby on Rails很火,他也不例外的學習了它。從那時候開始,Ryan Dahl的生活方式就是接項目,然后去客戶的地方工作,在他眼中,拿工資和上班其實就是去那里旅行。此后他去過很多地方,如阿根廷的布宜諾斯艾利斯、德國 的科隆、奧地利的維也納。
Ryan Dahl經過兩年的工作后,成為了高性能Web服務器的專家,從接開發應用到變成專門幫客戶解決性能問題的專家。期間他開始寫一些開源項目幫助客戶解決 Web服務器的高并發性能問題,嘗試過的語言有Ruby、C、Lua。當然這些嘗試都最終失敗了,只有其中通過C寫的HTTP服務庫libebb項目略有 起色,基本上算作libuv的前身。這些失敗各有各的原因,Ruby因為虛擬機性能太爛而無法解決根本問題,C代碼的性能高,但是讓業務通過C進行開發顯 然是不太現實的事情,Lua則是已有的同步I/O導致無法發揮性能優勢。雖然經歷了失敗,但Ryan Dahl大致的感覺到了解決問題的關鍵是要通過事件驅動和異步I/O來達成目的。
在他快絕望的時候,V8引擎來了。V8滿足他關于高性能Web服務器的想象:
- 沒有歷史包袱,沒有同步I/O。不會出現一個同步I/O導致事件循環性能急劇降低的情況。
- V8性能足夠好,遠遠比Python、Ruby等其他腳本語言的引擎快。
- JavaScript語言的閉包特性非常方便,比C中的回調函數好用。 </ol>
- 不再有Gatekeeper。取而代之的是TC(Technical Committee),也就是技術委員會。技術委員會基本上是由那些有很多代碼貢獻的core contributor組成,他們來決定技術的方向、項目管理和流程、貢獻的原則、管理附加的合作者等。當有分歧產生時(如引入feature),采用投 票的方式來決定,遵循少數服從多數的簡單原則。基本上原來由一個人擔任的Gatekeeper現在由一個技術委員會來執行。如果要添加一個新成員為TC成 員,需要由一位現任的TC成員提議。每個公司在TC中的成員不能超過總成員的1/3。
- 引入Collaborators。代碼倉庫的維護不僅僅局限在幾個core contributor手中,而是引入Collaborators,也就是合作者。可以理解為有了更多的core contributor。
- TC會議。之前的的溝通方式主要是分布式的,大家通過GitHub的issue列表進行溝通。這種模式容易堆積問題,社區的意見被接受和得到 處理取決于core contributor的情況。io.js會每周舉行TC會議,會議的內容主要就issue討論、解決問題、工作進展等。會議通過Google Hangout遠程進行,由TC贊同的委任主席主持。會議視頻會發布在油Tube上,會議記錄會提交為文檔放在代碼倉庫中。
- 成立工作組。在項目中成立一些細分的工作組,工作組負責細分方向上的工作推進。
- 新功能的激進。io.js盡管在架構層面依然保持著Node.js的樣子(由Ryan Dahl時確立),但是對于ECMAScript 6持擁抱態度。過去在Node.js中需要通過flag來啟用的新功能,io.js中不再需要這些flag。當然不用flag的前提是V8覺得這個 feature已經穩定的情況下。一旦最新的Chrome采用了新版本的V8,io.js保持很快的跟進速度。
- 版本迭代。io.js保持了較高頻率的迭代,以底層API改變作為大版本的劃分,但對于小的改進,保持每周一個版本的頻率。只要是改 進,io.js項目的TC和Collaborators都非常歡迎,大到具體feature或bug,小到文檔改進都可以被接受,并很快放出版本。
- issue反饋。Node.js的重要的貢獻者們都在io.js上工作,Node.js和io.js項目的問題反饋速度幾乎一致,但是問題處理速度上面io.js以迅捷著稱,基本在2-3天內必然有響應,而Node.js則需要1個禮拜才有回復。
- https://github.com/joyent/node/issues/9295
- https://github.com/iojs/io.js/issues/978
- https://github.com/iojs/io.js/issues/1336
- https://github.com/iojs/io.js/issues/1416
- https://github.com/iojs/io.js/labels/meta
- http://blog.nodejs.org/2015/05/08/transitions/
- http://blog.nodejs.org/2015/05/08/next-chapter/
- https://github.com/iojs/io.js/issues/1664
- http://tinyclouds.org/nodeconf2012.pdf
- https://www.joyent.com/blog/introducing-the-nodejs-foundation
- http://blog.nodejs.org/2015/05/15/node-leaders-are-building-an-open-foundation/
- https://medium.com/node-js-javascript/growing-up-27d6cc8b7c53
于是在2009年的2月,按新的想法他提交了項目的第一行代碼,這個項目的名字最終被定名為“node”。
2009年5月,Ryan Dahl正式向外界宣布他做的這個項目。2009年底,Ryan Dahl在柏林舉行的JSConf EU會議上發表關于Node.js的演講,之后Node.js逐漸流行于世。
以上就是Node.js項目的由來,是一個專注于實現高性能Web服務器優化的專家,幾經探索,幾經挫折后,遇到V8而誕生的項目。
Node.js項目的組織架構和管理模式
Node.js隨著JSConf EU會議等形式的宣傳下,一家位于硅谷的創業公司注意到了該項目。這家公司就是Joyent,主要從事云計算和數據分析等。Joyent意識到 Node.js項目的價值,決定贊助這個項目。Ryan Dahl于2010年加入該公司,全職負責Node.js項目的開發。此時Node.js項目進入了它生命歷程里的第二個階段:從個人項目變成一個公司組 織下的項目。
這個階段可以從2010年Ryan Dahl加入Joyent開始到2014年底Mikeal Rogers發起Node Forward結束,Node的版本也發展到了v0.11。這個時期,IT業中的大多數企業都關注過Node.js項目,如微軟甚至對于Node.js對 Windows的移植方面做過重要的貢獻。
這個時期可以的組織架構和管理模式可以總結為“Gatekeeper + Joyent”模式。
Gatekeeper的身份類似于項目的技術負責人,對技術方向的把握是有絕對權威。歷任的Gatekeeper為:Ryan Dahl、Isaac Z. Schlueter、Timothy J Fontaine,均是在Node.js社區具有很高威望的貢獻者。項目的法律方面則由Joyent負責,Joyent注冊了“Node.js”這個商 標,使用其相關內容需要得到法律授權(如筆者《深入淺出Node.js》上使用了Node.js的Logo,當時是通過郵件的形式得到過授權)。技術方面 除了Gatekeeper外,還有部分core contributor。core contributor除了貢獻重要feature外,幫助項目進行日常的patch提交處理,協助review代碼和合并代碼。項目中知名的core contributor有Ben Noordhuis,Bert Belder、Fedor Indutny、Trevor Norris、Nathan Rajlich等,這些人大多來自Joyent公司之外,他們有各自負責的重要模塊。Gatekeeper除了要做core contributor的事情外,還要決定版本的發布等日常事情。
Node.js成為Joyent公司的項目后,Joyent公司對該項目的貢獻非常大,也沒有過多的干涉Node.js社區的發展,還投入了較多 資源發展它,如Ryan Dahl、Isaac Z. Schlueter、Timothy J Fontaine等都是Joyent的全職員工。
Node.js社區的分裂
“Gatekeeper + Joyent”模式運作到2013年的時候都還工作良好,蜜月期大概中止于第二任Gatekeeper Isaac Z. Schlueter離開Joyent自行創建npm inc.公司時期。前兩任Gatekeeper期間,Node.js的版本迭代都保持了較高的頻率,大約每個月會發布一個小版本。在Isaac Z. Schlueter卸任Gatekeeper之后,Node.js的貢獻頻率開始下降,主要的代碼提交主要來自社區的提交,代碼的版本下降到三個月才能發 布一個小版本。社區一直期待的1.0版本遲遲不能發布。這個時期Node.js屬于非常活躍的時期,但是對于Node.js內核而言卻進展緩慢。技術方向 上似乎是有些不明朗,一方面期待內核穩定下來,一方面又不能滿足社區對新feature的渴望(如ES6的特性遲遲無法引入)。
第三任的Gatekeeper Timothy J Fontaine本人也意識到這個問題。從他上任開始,主要的工作方向就是解決該問題。他主要工作是Node on the road活動,通過一系列活動來向一些大企業用戶獲取他們使用Node.js的反饋。通過一些調研,他做了個決定,取消了貢獻者的CLA簽證,讓任何人可 以貢獻代碼。
盡管Timothy J Fontaine的做法對Node.js本身是好的,但是事情沒有得到更好的改善。這時候Node.js項目對社區貢獻的patch處理速度已經非常緩 慢,經常活躍的core contributor只有Fedor Indutny、Trevor Norris。另外還發生了人稱代詞的事件,導致Node.js/libuv項目中非常重要的貢獻者Ben Noordhuis離開core contributor列表,這件事情被上升到道德層面,迎來了不少人的謾罵。其中Joyent的前任CEO甚至還致信表示如果是他的員工,會進行開除處 理。這致使Node.js項目的活躍度更低。Node.js的進展緩慢甚至讓社區的知名geek TJ Holowaychuk都選擇離開Node.js而投入Go語言的懷抱。
可以總結這個時期是“Gatekeeper + Joyent”模式的末期。Joyent對于項目的不作為和其他層面對社區其他成員的干預,導致項目進展十分緩慢,用蝸牛的速度來形容一點也不為過。盡管 Timothy J Fontaine試圖挽回些什么,也有一些行為來試圖重新激活這個項目的活力,但是已經為時已晚。
這時一個社區里非常有威望的人出現了,他就是Mikeal Rogers。Mikeal Rogers的威望不是建立在他對Node.js項目代碼的貢獻上,他的威望主要來自于request模塊和JSConf會議。其中JSConf是 JavaScript社區最頂級的會議,他是主要發起人。
在2014年8月,以Mikeal Rogers為首,幾個重要core contributor一起發起了一個叫做“Node forword”的組織。該組織致力于發起一個由社區自己驅動來提升Node、JavaScript和整個生態的項目。
“Node forword”可以視作是io.js的前身。這些core contributor們在“Node forword”上工作了一段時間,后來因為可能涉及到Node這個商標問題,Fedor Indutny憤而fork了Node.js,改名為io.js,宣告了Node.js社區的正式分裂。
簡單點來說這件事情主要在于社區貢獻者們對于Joyent公司的不滿,導致這些主要貢獻者們想通過一個更開放的模式進行協作。復雜點來說這是公司 開源項目管理模式的問題所在,當社區方向和公司方向一致時,必然對大家都有好處,形同蜜月期,但當兩者步驟不一致時,分歧則會暴露出來。這點在 Node.js項目的后期表現得極為明顯,社區覺得項目進展緩慢,而Joyent公司的管理層則認為他穩定可靠。
io.js與Node.js advisory board
在“Node Forward”的進展期間,社區成員們一起溝通出了一個基本的開放的管理模式。這個模式在io.js期間得到體現。
io.js的開放管理模式主要體現在以下方面:
io.js項目從fork之后,于2015-01-14發布了v1.0.0版本。自此io.js一發不可收拾,以周為單位發布新的版本,目前已經發布到2.0.2。io.js項目與Node.js的不同在行為上主要體現在以下方面:
基本上而言原本應該屬于Node.js項目的活力現在都在io.js項目這里。如果沒有其他事情的發生,io.js可以算作社區驅動開源項目的成功案例了。
當然,盡管在Node.js這邊進展緩慢,但Joyent方面還是做出了他們的努力。在“Node Forward”討論期間,Joyent成立了臨時的Node.js顧問委員會 https://nodejs.org/about/advisory-board/ 。顧問委員會的主要目標與“Node Forward”的想法比較類似,想借助顧問委員會的形式來產出打造一個更加開放的管理模式,以找到辦法來平衡所有成員的需要,為各方提供一個平臺來投入資源到Node.js項目。
顧問委員會中邀請了很多重要的Contributor和一些Node.js重度用戶的參與。開了幾次會議來進行探討和制定新的管理模式。于是就出 現了一邊是io.js如火如荼發布版本,Joyent這邊則是開會討論的情況。顧問委員會調研了IBM(Eclipse)、Linux基金會、 Apache等,決定成立Node.js基金會的形式。
io.js與Node.js基金會
時間來到2015年1月,臨時委員會正式發布通告決定將Node.js項目遷移到基金會,并決定跟io.js之間進行和解。簡單點來說 Node.js方面除了版本的進展比較緩慢外,確實是在制定一個新的模式來確保Node.js項目的下一步發展,Joyent公司本著開放的原則,也做出 相當大的讓步,保持著較為和諧的狀態。
然而io.js動作太快,代碼的進展程度遠遠快于Node.js項目,和解的討論從2月開始討論,到5月才做出決定。這時io.js已經發布了它的2.0版本。
最終的結論是Node.js項目和io.js項目都將加入Node.js基金會。Node.js基金會的模式與io.js較為相似,但是更為健全。Mikeal Rogers在他的一篇名為 《Growing Up》 的文章中提到io.js項目需要一個基金會的原因。
io.js項目在技術方面的成熟度顯然要比最初的Gatekeeper時代要更為先進,給予貢獻者更多的管理權利。然而在市場和法律方面,還略顯 幼稚。最終無論是顧問委員會,還是io.js都選定以基金會的形式存在。這個基金會參考Linux基金會的形式,由董事會和技術委員會組成,董事會負責市 場和法律方面的事務,技術委員會負責技術方向。
就像《三國演義》所述:天下大勢,合久必分,分久必合。Node.js項目也從Joyent公司的懷里走出來,成長為基金會的形式,進入這個項目生命周期里第三個階段。
后續
從io.js的分裂到Node.js基金會,從外人看起來似乎如一場鬧劇一般,然而這個過程中可以看到一個開源項目自身的成長。盡管io.js將 歸于Node.js基金會,像一個離家出走的孩子又回家一般,它的出走可能要被人忘記,但從當初的出發點來說,這場戰役,io.js其實是贏家。窮則思 變、不破不立是對Joyent較為恰當的形容。如果Joyent提前能相當這些,則不會有社區分裂的事情發生。
Node.js處于停滯狀態的開發和io.js的活躍情況之間,目前免不了大量的Merge工作。作為和解的條件之一,Node.js基金會之后Node版本的發布將基于目前io.js的進展來進行。后續的合并工作示意如下:
now (io.js) v2. : v2.x | | : | v.10.x /--------------:-----------------\ Node.js 2.0 ____|____/ : \______|_____ \ : / \--------------:-----------------/ | | : | | (node.js) v.12.x : v.13.x v.14.x
在未完成合并之前,io.js會繼續保持發布。Node.js的下個大版本跨過1.0,直接到2.0。
io.js項目的TC將被邀請加入Node.js基金會的TC,畢竟兩者在技術管理方面達成了一致。基金會將在黃金和白銀會員中選舉出董事、技術委員會成員中選舉出技術委員主席。
對于成為Node.js基金會成員方面,企業可以通過贊助的方式注冊成為會員。
總結
一個開源項目成長起來之后,就不再是當初創始人個人維護的那個樣子了。Node.js項目的發展可以說展現了一個開源項目是如何成長蛻變成成熟項目的。當然我們現在說Node.js基金會是成功的還為時尚早,但是祝福它。