濤思數(shù)據(jù)創(chuàng)業(yè)初期,只有幾個人,人人都是十倍程序員。但7年之后,隨著組織的龐大以及代碼的增多,研發(fā)效率大為下降,為此我痛下決心,在今年十月份重組了公司最重要的資產(chǎn),研發(fā)部門。重組后,為提升研發(fā)效率和產(chǎn)品質(zhì)量,我強調(diào)一個原則:一切都要代碼化。今天我將公司的一篇內(nèi)部博客分享出來,供廣大的研發(fā)同學、研發(fā)管理人員參考。
公司為提升研發(fā)效率,提升產(chǎn)品質(zhì)量,將整個研發(fā)部門進行了重組,并將以前的測試部門轉(zhuǎn)為研發(fā)平臺部,這背后的邏輯是什么呢?我在會上介紹過緣由,但其中一條就是堅決貫徹執(zhí)行“一切都要代碼化”。我想給大家多解釋一下,為什么要這么做?為什么它能提升研發(fā)效率,進而提升產(chǎn)品質(zhì)量呢?
研發(fā)效率低下的幾大典型場景
軟件開發(fā),在人員規(guī)模就幾個人的時候,人效往往很高。但隨著項目本身的復雜度的增加,要處理的場景越來越多,代碼量也越來越大。比如TDengine,第一個版本不到15萬行代碼,但現(xiàn)在已經(jīng)是超過70萬行代碼,測試代碼都接近一百萬行了。到今天,TDengine這個軟件已經(jīng)不是幾個人能搞定了。隨著團隊規(guī)模的增加,協(xié)同溝通的成本急劇上升。而且為保證品質(zhì),團隊引入了各種質(zhì)量控制的流程,整個研發(fā)節(jié)奏慢了下來,人效大為下降。具體可以表現(xiàn)在幾個場景:
1. 研發(fā)在客戶現(xiàn)場解決了一個BUG,改了幾行代碼,客戶急著上線,但研發(fā)因為各種環(huán)境依賴,無法在自己筆記本上Build一個新的可以交付的版本,只能遞交PR,等著發(fā)版負責人發(fā)版,然后下載安裝。一般情況下,這一操作需要等待幾個小時,在現(xiàn)場支持的人只能干著急。
2. 一位新入職的研發(fā)同學,至少要花上好幾天時間才能自己獨立的寫程序、編譯、測試,中間還需要不斷的“騷擾”其他同事,問這問那。如果沒有人協(xié)助,估計一周都搞不定。因此新人入職,我們美其名曰“熟悉環(huán)境”。
3. 公司建有CI/CD系統(tǒng),看上去很不錯,但所有人遞交的PR都需要過一遍整個流程,特別是測試流程。TDengine整個測試例已經(jīng)超過1500個,跑完都要2個多小時,這樣導致一個PR的遞交,要等很長時間。如果遞交的PR有問題,還需要再遞交,因此讓新代碼的遞交效率大大降低。
4. 整個公司沒有人能說出來到底有哪些場景的測試例在跑,雖然有測試設(shè)計文檔,列出了哪些測試例,但實際跑的與文檔上差別太大。而且很多情況下,測試例各寫各的,雖然測試例的數(shù)量在不斷增長,但測試有重疊,覆蓋率依然不夠。
5. 要測試某個用戶場景,無論是研發(fā),還是售前、交付,第一件事情就是申請計算資源。雖然我們已經(jīng)有2600多個核的測試機房,但這些機器都被人為的分配給了不同的組和個人。因此要協(xié)調(diào)出新的資源,挺困難,不是鼠標點擊一下就能解決的,往往就要開會協(xié)調(diào),幾個人的一個小時就這樣過去了。
上面描寫的五個場景在TDengine全部存在。整體來講,我們研發(fā)效率是低下的。如果從我們對BUG修復的時長以及數(shù)目來看,與傳統(tǒng)的大公司的研發(fā)相比,效率已經(jīng)高不了多少,但與我們創(chuàng)業(yè)初期相比,1/3都沒有。由于效率低下,導致我們的投入不夠,也就導致產(chǎn)品的質(zhì)量難以保證。
效率低下的根本原因
隨著團隊規(guī)模的增大,為什么協(xié)同溝通成本就急劇增加?研發(fā)效率就大幅下降呢?仔細分析,有幾點原因:
1. 好些工作都難重復,都藏在個人的腦子里。比如開發(fā)環(huán)境的依賴,都是各搞各的。每個人都要下載各種軟件包、各種工具,讀一大堆文檔,按自己的理解做各種配置,最后工作,當然很開心。另外一個人,又是要走同樣的路,手腳快的,也許幾個小時搞定,但碰上手腳慢的,一天都搞不定,卡在什么地方,還沒人能幫。
2. 不重視工具、工作流管理的代碼,沒把他們納入代碼的版本管理。比如發(fā)版工作,本來應(yīng)該是全自動化,而且也確實做到了。但一旦發(fā)版的工作流做些修改,CI/CD又卡在一個人手里,取決于這個人的水平高低,有可能很快,也有可能很慢。但總之,即使水平低,你也沒辦法,因為其他人沒法上手馬上讓它工作,而且相當多程序員往往不屑于寫這類程序。因此讓CI/CD跑起來,只有這位“牛人”能做。
3. 文檔與代碼脫節(jié)。比如我們TDengine測試代碼,就與Testing Spec脫節(jié)。Testing Spec往往是過期的,初稿review之后再也不會有人改。新增、修改的測試例在文檔里是反映不出來的。
4. 對用戶手冊重視程度不足。雖然 TDengine 的用戶手冊已經(jīng)遠遠好于中國絕大部分技術(shù)公司,但與全球頂尖的軟件公司比,還有不小的差距。用戶手冊由于本身的性質(zhì),導致它很容易落后于代碼的更新。而且研發(fā)同學普遍的共識是,寫用戶手冊不是研發(fā)工作,無法體現(xiàn)自己研發(fā)水平,因此投入不夠。在這種情況下,售前、交付、還有用戶的問題,都只能依賴我們產(chǎn)品的“專家”來親自回答,而且有時自己都拿捏不準,還要問周圍同事大半天,才能給用戶一個精準的回答。而且因為他能回答客戶產(chǎn)品問題,理所當然,還會被大家認為是高手。
5. 公司計算、網(wǎng)絡(luò)資源的管理還是原始時代,完全是靠Excel表格人工在管理。
一切都需要代碼化
全球軟件開發(fā)行業(yè)發(fā)展到今天,早有了成熟的方法應(yīng)對這些效率低下、產(chǎn)品質(zhì)量難以保證的場景,那就是一切都要代碼化。因此我們會經(jīng)常聽到Infrastructure as code, Environment as code, Pipeline as code, Documentation as code, Security as code, Network as code這些詞。這些詞是”as code movement” 在一些具體場景的體現(xiàn)。代碼化的核心目的是讓一切可自動化、可重復、可回溯,每個研發(fā)不用做低水平的重復性的工作,從而提升研發(fā)效率,進而有更多資源投入來提升產(chǎn)品的質(zhì)量。針對TDengine,我們可以明顯看到需要做或改進的地方有:
1. Environment as code:即開發(fā)環(huán)境、測試環(huán)境的自動化部署。我們不能依賴某個人腦子的記憶或經(jīng)驗,依賴研發(fā)同學快速閱讀第三方工具用戶手冊、試錯的能力,而是要將這些經(jīng)驗、能力固化成為代碼。一個人趟過所有的坑后,通過代碼讓其他同事都能享受他工作的結(jié)果,一鍵就能把自己的環(huán)境設(shè)置好,根本不用去了解Maven怎么安裝,MQTT數(shù)據(jù)源怎么設(shè)置等等,而且其他同學可以在他代碼基礎(chǔ)上做調(diào)整。
2. Pipeline as code:CI/CD的workflow代碼化。我們早已代碼化,但要把這些代碼納入到正常的版本管理,任何人都可以在現(xiàn)有的代碼基礎(chǔ)上修改、優(yōu)化,增加新的步驟等。而且要保證我們的代碼不能有任何環(huán)境的依賴,比如某臺具體的測試機器,這樣任何人Clone完代碼后,自己一下就能把workflow搭建出來。同時,整個workflow包含的內(nèi)容要越來越多。我們已經(jīng)增加了Release Notes,測試覆蓋率報告、性能測試報告自動生成。今后我們還要看哪些內(nèi)容可以自動生成,哪些檢查工具可以加上。
3. Documentation as code:文檔代碼化。除用戶手冊之外,最重要的是測試例的列表。我們需要從測試例腳本本身自動生成測試例列表,而且自動分類。這樣讓任何人,包括售前、交付的同學,一看就知道到底測試過哪些場景,針對某個具體客戶,是否需要新增場景。用戶手冊我們已經(jīng)代碼化,但做的還不夠好,因此我們現(xiàn)在對于一個新的功能或BUG,研發(fā)負責人有項專門的工作,就是合并PR時,檢查用戶手冊是否有更新。
4. Benchmark as code:對比測試代碼化。TDengine與其他時序數(shù)據(jù)庫相比,有卓越的性能。但每個版本我們都要做對比測試,而且要不斷增加與其他競品的對比。我們已經(jīng)部分實現(xiàn),但還不夠徹底,有一定的環(huán)境依賴。
5. Infrastructure as code:即計算資源的分配要自動化。把我們內(nèi)部的服務(wù)器資源的管理完全虛擬化、腳本化,對于閑置的資源自動釋放。自動化后,我們一家100人的公司,測試機房有2600多個核,根本不會存在測試資源不夠的時候。要新的計算資源,幾秒鐘搞定。
對于研發(fā)團隊,現(xiàn)在我能看到無法完全代碼化的工作是產(chǎn)品設(shè)計文檔,有一些工具可以幫助大家,但難以100%代碼化。拋開設(shè)計文檔,其他所有工作都是可以,而且必須代碼化的。代碼化后,個人的經(jīng)驗、能力就轉(zhuǎn)化為團隊的經(jīng)驗和能力,溝通交流成本大幅下降,一切都是代碼說話。這也是我們?yōu)槭裁匆獙φ麄€研發(fā)團隊統(tǒng)計代碼量的原因。代碼量不是絕對,更不是唯一指標,代碼量大的同學,工作不一定出色,但代碼量一直很低的同學,工作是一定有問題的。在我們過去,有的同學一個月都沒有遞交過一次代碼,這種情況再也不能發(fā)生。
一切代碼化后的效果
一切代碼化后,很多工作改變了,我們可以明顯的看到如下的結(jié)果:
1. 任何人在自己不聯(lián)網(wǎng)的計算機上都可以打包、發(fā)布版本。如果在客戶現(xiàn)場發(fā)現(xiàn)BUG并解決了它,可以馬上給它安裝上自己的版本,而不會有任何不兼容的事情發(fā)生。
2. 任何人在自己計算機上,都可以跑測試,包括全量測試、穩(wěn)定性測試、性能測試、性能對比測試、檢查測試覆蓋率等,而且不依賴公司的測試資源。因此完成一項功能或解決一個BUG,自己就可以全部跑一次,以避免遞交PR時無法遞交。
3. 性能優(yōu)化的同學,可以一鍵先在自己計算機上跑性能測試,看性能是否確實提升了沒有,而不是直接遞交到測試平臺,等待結(jié)果之后再看。
4. 新加入的同事,根本不需要熟悉環(huán)境,幾個小時,就可以配置好開發(fā)環(huán)境,Clone代碼,編譯、運行、測試起來。手快的,就可以馬上開始debug了。
5. 客戶、售前、交付同學關(guān)于產(chǎn)品的問題,研發(fā)同學一律是把用戶手冊的截圖或鏈接發(fā)給對方。如果無法做到,馬上去修改文檔,遞交PR。這樣我們每個人都不用腦子里記住或記錄一些產(chǎn)品如何避坑的小技巧了。我們留給客戶的印象就是專業(yè),產(chǎn)品沒有瑕疵,出錯全怪我自己,是由于自己沒細看文檔。
6. 任何人,包括非研發(fā)團隊的同學,可以清晰的看到每個發(fā)布的版本,進行了哪些具體測試,發(fā)布的版本是否有任何報錯或報警。針對自己客戶的場景,馬上就知道還需要補充哪些測試用例,才能確保產(chǎn)品上線沒有問題。
7. 需要計算資源的同學,只要登錄內(nèi)部網(wǎng)站鼠標點擊幾下,想要的硬件資源、配置的軟件環(huán)境就馬上準備好了。
8. 在我詢問研發(fā)平臺組同學的工作時,如果問負責發(fā)版的同學,他的回答是“Jeff,我這周又把發(fā)版流程優(yōu)化、調(diào)整了一下,加了更多的檢查,來保證產(chǎn)品質(zhì)量”,而不是“我這周忙死了,發(fā)了幾個什么版本”。如果問穩(wěn)定性測試的同學,他的回答是“Jeff,這周我又新增了幾個破壞性的測試場景”,而不是“我這周發(fā)現(xiàn)了2個BUG”。問性能測試的同學,他的回答是“Jeff,這周我新增了幾個查詢場景的性能測試”,而不是“我這周完成了性能對比測試”。
一切代碼化還可以讓新人迅速進入角色,而不是受制于需要長時間溝通才能獲取的信息。每個人需要依靠自己的能力,而不是掌控的信息或資源,來成為研發(fā)高手。
結(jié)語
一切代碼化充分體現(xiàn)我們倡導的“公開、透明”的文化,也充分體現(xiàn)我們強調(diào)的“實事求是”的工作原則。研發(fā)就必須以代碼說話,而不是把很多東西記在腦子里,或者讓自己寫下的文檔或代碼生銹長霉,這樣才能形成團隊的力量,集體的智慧,而且隨著時間的推移,我們的積累就越來越多。效率提升之后,我們可以把省出的精力更多的傾注到創(chuàng)造性的工作上去,提升產(chǎn)品的品質(zhì),進而提升產(chǎn)品的市場競爭力,讓我們獲得商業(yè)成功。
陶建輝
濤思數(shù)據(jù)TDengine創(chuàng)始人



互聯(lián)網(wǎng).png)



-1.png)










伙伴.png)
伙伴.png)
伙伴.png)



