
大家好,我是張亮,目前任職當當架構部架構師一職,也是高可用架構群的一員。
首先我介紹一下項目背景。當當在 2015 年 9 月開始開源了内部使用的分布式作業排程架構——elastic-job,然後又于 2016 年 1 月 18 日開源了資料庫分庫分表中間件——sharding-jdbc。
當當後端使用 java 開發較多,是以這次做的開源項目也是基于 java 開發者而非産品型。目的是讓 java 程式員能夠順暢使用,對于非 java 使用者可能未必友好。這兩個開源項目的背景不太一樣,elastic-job 是先于公司使用,基本成熟之後再開源于社群。而 sharding-jdbc 是先開源至社群,再于公司内部同步推廣落地。
截止到目前,我們做了 4 個月的開源相關的事情,雖然經驗并不豐富,但是也想和大家分享一下與開源相關的經驗和問題。
在做新項目之前,我們做過大量的調研。
分布式作業排程這塊,quartz 可做到依賴于資料庫的高可用,但無彈性排程功能。tbschedule 這樣老一些的項目在時間排程方面又不如 quartz 強大。
分庫分表的資料庫中間層方面,雖然有 cobar、tddl、mycat、compass、oceanus、kingshard、atlas 等一系列開源産品,但目前确實無法完全覆寫我們的需求。
我們選擇做一個面向開源,且不與業務系統耦合的純技術元件。也就是說,底層的這些元件,并不是從業務系統分離出來的,而是完全從技術元件的角度去開發,然後再向業務系統發起落地。是以,這兩個元件可以在隻做很少改動的情況下開源。
既然已經決定開源,項目的品質要求即是以開源的标準來要求。
公開給所有人的并不隻是功能和文檔,而是全部代碼,這樣的品質要求和做一個内部項目是不同的。我們認同馬丁福勒這位代碼溝通大師的理念,任務代碼是給人看的,不是僅僅給機器編譯用的。維護一個有缺陷但是代碼清晰的項目,遠比維護一個代碼混亂但暫時未發現缺陷的項目要更加容易、更加受歡迎。
測試用例的覆寫率是另一項重要标準,我們要求測試覆寫率盡量達到 80% 以上。如此才可以放心的重構和完善新功能。目前我們兩個開源項目的測試覆寫率均超過 90%。
代碼要完全掌控,不能允許有誰都不敢碰的黑箱存在。
文檔要清晰,代碼不能代替文檔。代碼寫的再清晰漂亮,很多使用者也是通過文檔來了解并使用項目的,通讀代碼的使用者畢竟是少數。但文檔絕不是越多越好,一定要适中,資訊量爆炸不利于資訊的吸收消化和檢索。
項目是否靠譜,是否穩定,是否可以拿來即用,是開發者選擇使用開源項目要面對的問題。以下三點可能會有助于開發者選擇這個開源項目信心的提升。
隻要自己的公司在大規模使用,則至少證明在某些場景下,項目是穩定的。公司案例的推廣和分享有助于開發者選擇。
需要通過公布疲勞測試的穩定性,性能測試的對比場景等資料提升使用者信心。
代碼需精雕細琢。舉個例子,sharding-jdbc 一共開發了三個月多一些,核心代碼一個月左右就開發完成了,剩下兩個月都是在打磨。主要包括整體流程梳理、子產品拆分規劃、代碼可讀性重塑、封裝粒度縮小等。開源項目是否可持續發展的關鍵點即在于此,這是對一個項目負責的态度。
我看到過的一個開源的項目,使用的 sql 解析完全是從第三方的 sql 解析包中複制過來,除去修改包名,大段大段的英文注釋都沒有改。而 sql 解析一般使用 javacc 這樣的技術生成的代碼,這種代碼動辄上萬行,難于維護。這等于是将引用第三元件的技術債放到了自己的項目中,這種做法是不太負責任的。
我們更傾向于需要一個 qq 群,用于輕便和愉快的溝通,也便于頭腦風暴。部分開發者屬于内向型,如果是 issue 或者郵件這種溝通方式,他們未必會采用。qq 群的另一個好處是提升親和度和社群粘性。qq 群中最好有一個活躍的組員是項目主導人員,及時溝通和回報項目情況。
開源項目一旦更新,是首發于 github 還是先于公司内部釋出。有些公司内部的比較着急的需求,需要在内部改完直接使用,長久下去會導緻公司内部代碼和開源版本混亂,不易維護。個人傾向于維護統一版本,先于社群開源,再拉取到公司的 maven 私服。這樣做的好處是優秀的想法不會滞後,而且可利用社群活躍度規避一些潛在風險。
開源項目一般難度會大于業務項目。這裡以 elastic-job 和 sharding-jdbc 舉例。兩個項目的難度展現在不同的地方。elastic-job 屬于分布式架構,代碼編寫并不難,難點在于分布式環境下的調試和問題重制。sharding-jdbc 剛好相反,調試難度不高,一條 sql 能否正确執行,這個環境非常容易重制,但編碼難度卻較大,sql 解析、路由、歸并的難度遠遠大于一般項目。
針對于這樣的問題,為了可以讓更多的人參與項目貢獻,我們考慮把任務分級,分為簡單型、長期型、讨論型、缺陷型和技術難點型。
簡單型例如運維頁面由中文專為支援多語言,這樣的任務可以讓有興趣的社群人員參與開發,并無太多門檻。
長期型屬于核心任務,最好由資深的開發人員或者項目的主導人員完成,比如:作業系統增加任務依賴。分布式資料庫增加柔性最終一緻性的事務。
讨論型一般會在 qq 群,wiki,issue 等平台讨論,比如 roadmap 先做哪些,某個具體任務的取舍等,最終會轉化為其他的任務類型,當然,一般不會轉化為簡單型。
缺陷型屬于快速響應的任務,在下個更新版本就會釋出。
技術難點型需要做調研,調研明白之後才決定如何做,有這方面技術經驗的社群人員可以提供更多的幫助。
開源之後必然會吸引一些愛好者關注。有些愛好者因為時間關系,并未閱讀代碼,甚至未閱讀文檔,就直接問一些基礎問題。有些愛好者因為經驗尚淺,會問一些和項目不直接相關的問題,比如:maven,zookeeper 怎麼用之類的。可能會導緻項目 master 浪費一定時間。
很多愛好者将項目用于自己公司的系統,也确實做了一些改進。但是限于時間原因,未能将代碼品質控制的很好,或者未能完全剝離公司的業務場景。這樣就很難再将有意義的更新回報至社群。
項目小團隊集中開發時,這個問題并不明顯。一旦貢獻者多了,代碼評審,品質管控,處理 pull request 等就會比較難。
總的來看,以上當當開源的經曆主要介紹了初創開源項目從 0 到 1 的過程,在以後肯定需要進一步完善并面對新的問題,以後的問題和上面說的也會有很大差别。但我們也相信,更多同行面臨的是我們上面碰到的新的項目從 0 到 1 的過程,希望通過以上的分享,吸引更多感興趣的同行一起加入到開源的大家庭,共同推進技術的進步。
====================================分割線================================