編者按:本文是張亮在高可用架構群新年聚會暨架構開源研討會上的分享。轉載請註明來自高可用架構公眾號「ArchNotes」。
張亮,當當網架構師、噹噹技術委員會成員、消息中間件組負責人。對架構設計、分布式、優雅代碼等領域興趣濃厚。目前主導噹噹應用框架 ddframe 研發,並負責推廣及撰寫技術白皮書。
「我們認同馬丁福勒這位代碼溝通大師的理念,任務代碼是給人看的,不是僅僅給機器編譯用的。維護一個有缺陷但是代碼清晰的項目,遠比維護一個代碼混亂但暫時未發現缺陷的項目要更加容易、更加受歡迎。」 —— 張亮
大家好,我是張亮,目前任職噹噹架構部架構師一職,也是高可用架構群的一員。
首先我介紹一下項目背景。噹噹在 2015 年 9 月開始開源了內部使用的分布式作業調度框架——elastic-job,然後又於 2016 年 1 月 18 日開源了資料庫分庫分表中間件——sharding-jdbc。
噹噹後端使用 Java 開發較多,所以這次做的開源項目也是基於 Java 開發者而非產品型。目的是讓 Java 程式設計師能夠順暢使用,對於非 Java 用戶可能未必友好。這兩個開源項目的背景不太一樣,elastic-job 是先於公司使用,基本成熟之後再開源於社區。而 sharding-jdbc 是先開源至社區,再於公司內部同步推廣落地。(小編:點擊文末連結了解 elastic-job 10 大特性介紹)
截止到目前,我們做了 4 個月的開源相關的事情,雖然經驗並不豐富,但是也想和大家分享一下與開源相關的經驗和問題。
1. 開源初心1.1 為什麼要做新項目?
在做新項目之前,我們做過大量的調研。
分布式作業調度這塊,quartz 可做到依賴於資料庫的高可用,但無彈性調度功能。tbschedule 這樣老一些的項目在時間調度方面又不如 quartz 強大。
分庫分表的資料庫中間層方面,雖然有 cobar、tddl、mycat、compass、oceanus、kingshard、atlas 等一系列開源產品,但目前確實無法完全覆蓋我們的需求。
1.2 做成什麼樣?
我們選擇做一個面向開源,且不與業務系統耦合的純技術組件。也就是說,底層的這些組件,並不是從業務系統分離出來的,而是完全從技術組件的角度去開發,然後再向業務系統發起落地。所以,這兩個組件可以在只做很少改動的情況下開源。
1.3 標準
既然已經決定開源,項目的質量要求即是以開源的標準來要求。
公開給所有人的並不只是功能和文檔,而是全部代碼,這樣的質量要求和做一個內部項目是不同的。我們認同馬丁福勒這位代碼溝通大師的理念,任務代碼是給人看的,不是僅僅給機器編譯用的。維護一個有缺陷但是代碼清晰的項目,遠比維護一個代碼混亂但暫時未發現缺陷的項目要更加容易、更加受歡迎。
測試用例的覆蓋率是另一項重要標準,我們要求測試覆蓋率儘量達到 80% 以上。如此才可以放心的重構和完善新功能。目前我們兩個開源項目的測試覆蓋率均超過 90%。
代碼要完全掌控,不能允許有誰都不敢碰的黑箱存在。
1.4 目的
1.4.1 反饋社區。每個開發者都或多或少的使用過開源產品。在使用開源的同時儘量的反饋社區,讓開源成為良性循環。
1.4.2 吸取社區精華。使用的人越多,看代碼的人越多,項目的缺陷和風險就會越小。而且眾多社區成員的使用,有助於疑難問題重現。比如:我們公司內部的 ZooKeeper 環境比較快,延遲低,一些分布式的問題就較少發生。但有的公司網絡環境稍差,就會產生 ZooKeeper 延遲導致的一些問題。發現問題的途徑越多就越有利於項目的健康發展。而且社區人員確實反饋了一些關鍵問題,貢獻了關鍵代碼,這些代碼也解決了噹噹內部的一些部分使用問題。
1.4.3 提升公司技術品牌。開源之後收到越來越多的人詢問噹噹是否還招人,也更多收到了討論技術問題的郵件和 QQ。這些影響都是潛移默化的,會漸漸的讓公司的技術影響力提升。對於不發出技術聲音的網際網路公司,可能會越來越難招募到優秀的開發者。
2. 經驗分享2.1 文檔問題
文檔要清晰,代碼不能代替文檔。代碼寫的再清晰漂亮,很多使用者也是通過文檔來了解並使用項目的,通讀代碼的使用者畢竟是少數。但文檔絕不是越多越好,一定要適中,信息量爆炸不利於信息的吸收消化和檢索。
2.2 信任度問題
項目是否靠譜,是否穩定,是否可以拿來即用,是開發者選擇使用開源項目要面對的問題。以下三點可能會有助於開發者選擇這個開源項目信心的提升。
2.2.1 公司案例
只要自己的公司在大規模使用,則至少證明在某些場景下,項目是穩定的。公司案例的推廣和分享有助於開發者選擇。
2.2.2 測試數據
需要通過公布疲勞測試的穩定性,性能測試的對比場景等數據提升使用者信心。
2.2.3 通過代碼展現實力
代碼需精雕細琢。舉個例子,sharding-jdbc 一共開發了三個月多一些,核心代碼一個月左右就開發完成了,剩下兩個月都是在打磨。主要包括整體流程梳理、模塊拆分規劃、代碼可讀性重塑、封裝粒度縮小等。開源項目是否可持續發展的關鍵點即在於此,這是對一個項目負責的態度。
我看到過的一個開源的項目,使用的 SQL 解析完全是從第三方的 SQL 解析包中複製過來,除去修改包名,大段大段的英文注釋都沒有改。而 SQL 解析一般使用 javaCC 這樣的技術生成的代碼,這種代碼動輒上萬行,難於維護。這等於是將引用第三組件的技術債放到了自己的項目中,這種做法是不太負責任的。
2.3 溝通問題
我們更傾向於需要一個 QQ 群,用於輕便和愉快的溝通,也便於頭腦風暴。部分開發者屬於內向型,如果是 issue 或者郵件這種溝通方式,他們未必會採用。QQ 群的另一個好處是提升親和度和社區粘性。QQ 群中最好有一個活躍的組員是項目主導人員,及時溝通和反饋項目情況。
2.4 版本問題
開源項目一旦更新,是首發於 github 還是先於公司內部發布。有些公司內部的比較著急的需求,需要在內部改完直接使用,長久下去會導致公司內部代碼和開源版本混亂,不易維護。個人傾向於維護統一版本,先於社區開源,再拉取到公司的 maven 私服。這樣做的好處是優秀的想法不會滯後,而且可利用社區活躍度規避一些潛在風險。
2.5 技術難度問題
開源項目一般難度會大於業務項目。這裡以 elastic-job 和 sharding-jdbc 舉例。兩個項目的難度展現在不同的地方。elastic-job 屬於分布式框架,代碼編寫並不難,難點在於分布式環境下的調試和問題重現。sharding-jdbc 剛好相反,調試難度不高,一條 SQL 能否正確執行,這個環境非常容易重現,但編碼難度卻較大,SQL 解析、路由、歸併的難度遠遠大於一般項目。
針對於這樣的問題,為了可以讓更多的人參與項目貢獻,我們考慮把任務分級,分為簡單型、長期型、討論型、缺陷型和技術難點型。
簡單型例如運維頁面由中文專為支持多語言,這樣的任務可以讓有興趣的社區人員參與開發,並無太多門檻。
長期型屬於核心任務,最好由資深的開發人員或者項目的主導人員完成,比如:作業系統增加任務依賴。分布式資料庫增加柔性最終一致性的事務。
討論型一般會在 QQ 群,wiki,issue 等平臺討論,比如 roadmap 先做哪些,某個具體任務的取捨等,最終會轉化為其他的任務類型,當然,一般不會轉化為簡單型。
缺陷型屬於快速響應的任務,在下個升級版本就會發布。
技術難點型需要做調研,調研明白之後才決定如何做,有這方面技術經驗的社區人員可以提供更多的幫助。
3. 未解決問題3.1 時間分配問題
開源之後必然會吸引一些愛好者關注。有些愛好者因為時間關係,並未閱讀代碼,甚至未閱讀文檔,就直接問一些基礎問題。有些愛好者因為經驗尚淺,會問一些和項目不直接相關的問題,比如:maven,zookeeper 怎麼用之類的。可能會導致項目 master 浪費一定時間。
3.2 技術反饋問題
很多愛好者將項目用於自己公司的系統,也確實做了一些改進。但是限於時間原因,未能將代碼質量控制的很好,或者未能完全剝離公司的業務場景。這樣就很難再將有意義的更新反饋至社區。
3.3 多人合作質量保障問題
項目小團隊集中開發時,這個問題並不明顯。一旦貢獻者多了,代碼評審,質量管控,處理 pull request 等就會比較難。
總的來看,以上噹噹開源的經歷主要介紹了初創開源項目從 0 到 1 的過程,在以後肯定需要進一步完善並面對新的問題,以後的問題和上面說的也會有很大差別。但我們也相信,更多同行面臨的是我們上面碰到的新的項目從 0 到 1 的過程,希望通過以上的分享,吸引更多感興趣的同行一起加入到開源的大家庭,共同推進技術的進步。
4. 參考閱讀新一代分布式任務調度框架:噹噹 elastic-job 開源項目的10項特性(點擊圖片進入)
本文來自微信公眾號高可用架構: