研发效能提升最佳实践的探索
GIAC(GLOBAL INTERNET ARCHITECTURE CONFERENCE)是長期關注互聯網技術與架構的高可用架構技術社區和msup推出的,面向架構師、技術負責人及高端技術從業人員的年度技術架構大會,是中國地區規模最大的技術會議之一。
第六屆GIAC,將從互聯網架構最熱門的前沿技術、技術管理、系統架構、大數據和人工智能、移動開發和語言、架構相關等領域,分享有典型代表的技術創新及研發實踐的架構案例。
在團隊協作專題,騰訊研發效能資深專家茹炳晟發表了題為《研發效能提升最佳實踐的探索》的主題演講。
茹炳晟,TEG-基礎架構部-研發效能中心專家工程師,業界知名實戰派軟件質量和研發工程效能專家,騰訊云最具價值專家TVP,中國商業聯合會互聯網應用技術委員會智庫專家,暢銷書《測試工程師全棧技術進階與實踐》和《高效自動化測試平臺:設計與開發實戰》作者,InfoQ極客時間《軟件測試52講-從小工到專家的實戰心法》作者,曾參與DevOps能力成熟度模型國家標準的編寫,也參與設計了DevOps企業教練的國際認證課程。
以下為演講實錄:
很榮幸受GIAC全球互聯網架構大會的邀請擔任了本屆大會“測試前沿技術“的出品人,同時也受邀發表了研發效能提升的主題演講。這里我把本次演講的精華部分做了一個簡單的梳理,希望能夠給關注研發效能提升的同學帶了啟發和幫助。以下是主要內容回顧,歡迎大家拍磚。
現代的軟件行業已經不再是以前“大魚吃小魚“的時代了,而是轉變成了”快魚吃慢魚“的時代。對于很多大型傳統軟件企業,原本“大“是其優勢,現在卻陷入了”大船難掉頭“的尷尬。對于大量小而美的互聯網軟件項目,當創意和細分領域被確認之后,各大友商比拼的就是研發能力,具體來講就是從需求轉化成軟件或者服務的能力,這其中研發效能的高低對于需求轉化速率起到了至關重要的作用。同時,如何有效降低研發和運維的成本也是研發效能需要關注的重要課題,尤其是大型互聯網項目,當某個環節哪怕只有少量優化的時候,由于其規模效應(比如集群規模,用戶流量等)的放大作用,最終節省的成本也會是相當可觀的。
和敏捷的概念類似,到底什么是研發效能其實很難精確定義。其實很多復雜概念不是定義出來的,而是逐步演化出來的,是先有現象再找到合適的表述。要理解這類復雜的概念,最好的方法是理清發展脈絡,回到歷史中,回到誕生的時間,漫步一遍它的發展歷程,才能真正理解其本質。但是由于時間關系,本次演講我們沒有足夠的時間帶著大家重走一遍歷史,所以我準備先通過幾個案例讓大家能夠先直觀的感受一下“研發效能提升之美“。
先來看第一個例子,很多時候我們在做產品原型設計的時候都需要借助產品原型工具來實現產品GUI界面的設計,以此作為溝通的基礎去開展后續的工作。但是你會發現即使已經有了類似Axure和Modao等原型工具,但是“畫界面“的成本依然很高。這里介紹一種可以將圖片GUI設計稿,甚至是手畫GUI設計稿轉化成目標平臺代碼的一鍵自動化生成方案。
在上面的例子中,先手繪GUI界面設計,然后通過Sketch2Code可以直接轉換成目標平臺的代碼,如果你指定的目標平臺是Web,那就直接生成html,如果你指定的目標平臺是iOS,那就會生成XCode的項目,通過編譯打包后就可以直接在iPhone上安裝執行了。這種方式的引入將大幅提升原型構建環節的效率。
再來看第二例子。API接口測試過程中,輸入參數臨界值沒有妥善處理的問題很常見,比如某個輸入參數是String類型,但是代碼實現中沒有考慮String變量取值為NULL等情況。這類問題通常都會在后期API集成測試或者聯調階段才會集中被發現,此時發現再去修復的成本通常都會比較高,而且修復之后還要考慮回歸測試的成本。所以我們可以引入一種機制,去主動掃描獲取API輸入參數的類型,然后根據參數類型生成容易出錯的取值,用這些取值自動調用API,如果發生500錯誤或者拋異常就是發現了問題。(比如,對于String類型的輸入參數就可以生成NULL,超長的字符串,包含非英語字符的字符串,SQL注入字符串等等。)進一步我們可以把這個方案和CI流水線集成,在CI執行過程中主動執行此類測試,以求問題更早地被暴露。
上面兩個例子都是由技術主導的。接下來的例子就和技術沒有太大關系了,而是由流程主導的。上面圖中廚師做三明治,左邊圖中由于各個食材擺放沒有特定的順序,造成廚師必須不斷來回走動才能完成任務,而右邊圖中食材按使用順序擺放,廚師可以站在原地輕松完成三明治的制作,大大節省了不必要的走動時間,從而大幅度提升了效率。由此可見,效率的提升既可以由技術來驅動,也可以由流程來驅動。
看完了上面的例子,我想你已經對研發效能提升有了一個非常感性的認識了。接下來,我們來看一下研發效能的本質。如果要用一句話來總結研發效能的話,我會用“順暢、高質量地持續交付有效價值的閉環“。解釋一下其中幾個關鍵概念:
順暢:價值的流動過程必須順暢,沒有阻礙
高質量:如果質量不行,流動越快,死的也會越快
持續:不能時斷時續,小步快跑才是正道,不要憋大招
有效價值:這是從需求層面來說的,你的交付物是不是真正解決了用戶的本質問題。(關于本質問題我想多說一句,女生減肥不是本質問題,女生愛美才是,可以自己體會一下。)
閉環:強調快速反饋的重要性
?在這個概念的引導下,我覺得五個持續(持續開發,持續集成,持續測試,持續交付和持續運維)是這個概念能夠落地的必要實踐。與此同時,我們還需要從流動速度,長期質量,客戶價值以及數據驅動四個維度來對研發效能進行有效的度量。
上面是從概念層面描述了研發效能,是不是感覺有點教條,其實我也覺得。所以下面我準備用通俗的例子來說說我對研發效能的理解。
左手邊的圖是所謂的“方輪子“效應。在前面使勁拉車的是老板,在后面使勁推車的是員工,老板關注的是大趨勢和方向,是向前看的,很難發現車的輪子是方的,拉車的員工可能看到了方輪子,但是鑒于老板在前使勁拉,所以絲毫不敢停下腳步,只能硬著頭皮使勁推。而在邊上提議換個圓形輪子的同學被無情地忽略了,換個圓輪子的確要額外的停頓,殊不知那是為了讓后面可以跑得更快更久。(題外話:突然腦中閃過一個酒店的slogan,知停而行)。你可能已經聯想到了,這里的圓輪子其實就是工程效能。
?右手邊的圖根據事情的重要程度和緊迫程度分成了四個象限。我們這里只討論A象限和B象限。A象限是重要但不緊迫,通常是一些基礎性長期重要的事情,比如搶占市場的新產品規劃,基礎設施建設,流程優化,人才培養等,我喜歡把這個象限稱為“未雨綢繆象限“。B象限是既重要又緊迫,通常是一些必須立馬處理的事情,比如系統故障,線上缺陷修復等,我常把這個象限稱為“救火象限“。?
理想情況下更多的時間占比應該放在“未雨綢繆象限“,少量的時間用于“救火象限“。
“未雨綢繆象限“做好了,“救火象限“事件的概率會變小。如果一個公司大部分時間在救火,通常說明這兩個象限的時間分配失衡或者倒掛了,需要關注投資那些長期重要但不緊迫的事情。
對于軟件研發而言,“未雨綢繆象限“中最重要的一環就是研發效能。
最后用一個更形象的例子做個比喻,相信大家都聽過鵝生金蛋的故事。是不是鵝生的金蛋越多,效能就越高呢?其實不是,一味地讓鵝全日午休地生金蛋早晚會把鵝累死,這不是可持續的長遠戰略。真正的效能應該是讓鵝生鵝,鵝再生鵝,讓更多的鵝一起來下金蛋。
騰訊TEG內部快速發展中的智研平臺,阿里已經走向產品化的云效平臺,百度基于工程效能白皮書來落地的效率云等等都是研發效能領域的標桿,可是你有沒有想過,為什么最近幾年各大行業龍頭企業都紛紛開始在研發效能領域發力,而且步調如此一致,我認為背后的原因有以下這么三點:
就像“中臺“概念一樣,現在很多大企業的產品線非常廣,其中存在大量重復的輪子,如果我們關注業務上的重復輪子,那么就是業務中臺;如果我們關注數據建設上的重復輪子,那么就是數據中臺;如果我們關注研發效能建設上的重復輪子,那就是研效平臺,其實研效平臺在某種程度上也可以稱之為”研發效能中臺“,其目標是實現企業級夸產品夸項目的研發能力復用,避免原來每條產品線都在做研發效能所必須的”0到1“,沒人有精力去關注更有價值的”1到n“?,F在的研效平臺會統一來打造組織級別通用研發能力的最佳實踐平臺。
從商業視角來看,現在toC產品已經趨向飽和,過去大量閑置時間等待被APP填滿的紅利時代已經一去不復返了,以前業務發展極快,那么用燒錢的方式(粗放式研發,人海戰術)換取更快的市場占有率達到贏家通吃是最佳選擇,那個時代關心的是軟件產品輸出,研發的效率都可以用錢填上。而現在toC已經逐漸走向紅海,同時研發的規模也比以往任何時候都要大,是時候要勒緊褲腰帶過日子了,當開源(開源節流中的開源)遇到瓶頸了,節流就應該發揮作用。這個節流就是研發效能的提升,同樣的資源,同樣的時間來獲得更多的產出。
從組織架構層面看,很有企業都存在“谷倉困局“,就像上面第二張圖展示的,研發各個環節內部可能已經做了優化,但是光環節的協作可能就會有大量的流轉與溝通成本,從而影響全局效率?;诹鞒虄灮?#xff0c;打破各個環節看不見的墻,去除不必要的等待,提升價值流動速度正是研發效能試圖解決的一大類問題。
這頁Slides是從軟件開發、測試和發布的視角羅列了各個階段研發效能提升需要關注的問題。其主線是圍繞CI/CD的一些列實踐。由于篇幅原因,我這里就不一一展開了,只舉幾個例子讓大家有個感性的認識。
可以通過All-in-one的開發環境降低每位開發人員開發環境準備的時間成本,同時又能保證開發環境的一致性。更高級的玩法是使用云端IDE,實現只要有瀏覽器就能改代碼。
可以借助基于AI的代碼提示插件,大幅度提升IDE中代碼的開發效率。同樣輸入一段代碼,不借助AI代碼提示插件,需要敲擊鍵盤200次,啟用插件可能只需要50次鍵盤敲擊。
代碼的靜態檢查沒有必要等到代碼遞交后由CI中的Sonar流程來發起,那個時候發現問題再修復為時已晚,完全可以通過Sonar Lint插件結合IDE實時發起本地的代碼檢查,有問題直接在IDE中提示,直接修復。
單元測試比較耗費時間,可以借助EvoSuite之類的工具降低單元測試的開發工作量。
對于規模較大的項目,每次修改后編譯時間比較長??梢圆捎迷隽烤幾g,甚至是分布式編譯(Distcc和CCache)提升效率。
前端開發可以借助JRebel和Nodemon之類的工具使前端開發預覽的體驗更流暢。
選擇適合項目的代碼分支策略對提升效率也大有幫助。
構建高度自動化的CI和CD流水線將大幅提升價值的流轉速率。
選擇合適的發布策略也會對效能和風險之間的平衡起到積極的作用。比如架構相對簡單,但是集群規模龐大,優選金絲雀,如果架構比較復雜,但是集群規模不是太大,可能藍綠發布更占優勢。
…
從上面的描述我們可以看到,研發效能的提升涉及的面很廣,既有基于技術的,也有基于流程的,那么在實際工程實踐中,我們又該如何來落地研發效能提升呢?我主張的觀點是“用MVP(Minimum Viable Product)的思想來提升研發效能“。
MVP這個概念來自于Eric Rise的《精益創業》一書,核心思想是是指以最低成本盡可能展現核心概念的產品策略,即是指用最快、最簡明的方式建立一個可用的產品原型,這個原型要表達出你產品最終想要的效果,然后通過迭代來完善細節。
這個思想特別適用于研效平臺的建設,我們必須在識別出待解決的研效問題之后,先給出最簡單的解決方案,然后在后面的實踐中不斷優化和迭代,如果我們試圖關起門來打造一個研效平臺,指望等所有功能都完美了再推給業務線團隊使用,那必然是死路一條。
還有必要特別指出一下MVP的常見誤區。實現了某一個功能但是暫時對客戶沒有實際價值,而要等后面功能出來后才能對客戶有用,這個不是MVP。MVP追求的是“麻雀雖小五臟俱全“,也就是實現的功能點可以很小,可以比較簡陋,但是對客戶有價值是必需的。用上圖的兩個三角形來說的話,”橫切“不是MVP,”豎切“才是MVP。
所以放到研發效能這個領域,我們要保證我們的做的研效工具一定是能解決實際痛點的,雖然一開始的方法可以比較簡陋。從產品的視角來看,研發平臺本身和一般的軟件產品沒有本質區別,也需要不斷迭代和持續改進。
這里開始是本次分享最硬核的部分,這也是我自己對如何推行研發效能提升的一個階段性總結。
常有人問我說,你之前主導的研效提升項目都獲得了成功,如果請你過來,幾年可以做好?這個其實是一個無解的問題。一定程度上,投入大,周期就會短,但是,實施周期不會因為投入無限大而無限變短。我們可以避開很多曾經踩過的坑,盡量少走彎路,但是,適合自己的路子還是要靠自己走出來,拔苗助長只會損害長期利益,買了一輛跑車,你就能成為賽車手嗎?鑒于此,我結合自己繳過的學費、踩過的坑總結了上圖中的8個建議供大家參考。接下來我會挨個做解讀。
?第一點是“從痛點入手“。很多時候,當我們手上拿著錘子的時候,看什么都像釘子。但是研發效能提升恰好是反過來了,我們要先找到哪些是最礙眼的釘子,然后用體系化的方法論去打造合適的錘子。
所以在推行研發效能的早期階段,我們通常會采用自下而上的策略,從一個個工程實踐中的實際痛點(釘子)入手,從解決問題的角度打造研效提升的亮點,此時我們追求的是”短平快“,問題點逐個擊破的原則。比如下面這些場景:
本地編譯耗時長:提供增量編譯和分布式編譯能力
本地測試困難,測試環境準備復雜且耗時:基于K8S的Pod提供一鍵搭建測試環境的能力
自動化測試用例數量大,執行回歸時間過長:采用并發測試用例執行機制,使用幾百幾千臺測試執行機并行執行用例,實現用硬件資源換時間
自動化測試用例維護成本高:測試用例采用模塊化和分層體系,實現低成本的自動化用例維護
測試數據準備困難:引入統一測試數據服務(Test Data Service)能力
研發后期階段,代碼遞交集中,缺陷井噴:推行測試左移,鼓勵研發自測,推行”誰開發,誰測試,誰上線,誰Oncall“
性能缺陷在研發后期發現,修復重測成本高居不下:從性能測試轉變為性能工程,讓性能融入軟件研發的各個環節,而不是最后的一錘子買賣
安全問題頻現:將安全測試能力納入研發的全生命周期,實現DevSecOps,而不是早期的SDL
集群規模龐大,發布過程耗時過長:各個層級的并發部署能力,集群內節點的并發,集群間的并發等
項目的過程數據都是后期集中填充,失去度量意義:項目過程數據由工具自動填充,不再依賴工程師手工輸入。比如開發完成時間不再依賴于開發人員手工填寫,而是由Jenkins構建完成后自動填寫,以保證所有過程數據的真實有效性,從而為后面的度量和改進提供可靠的信息輸入。
…
第二條是“從全局切入“。很多時候我們會嘗試去優化某個具體的環節,而忽略了全局優化的可能。
?舉個例子,我們去醫院看病,通常是掛號排隊半小時,實際掛號可能就兩分鐘,接下來又是漫長的排隊等待等待醫生就診,好不容易排到了進去可能不到五分鐘就被要求去驗血…。整個過程中實際有效時間的占比很小。如果這個時候我們還試圖去優化掛號本身的時間,而不去關注優化各個環節的等待時間顯然是錯誤的方向,所以效率提升既要關注單個步驟的優化,也要專注減少步驟與步驟之間的無用等待。這一點體檢中心就比公立醫院做的好太多了,你很少會見到體檢中心每個科室門口都大排長龍的情景,因為體檢中心出于經濟利益的考慮會關注吞吐量,會通過全局排隊調度優化來實現更高的盈利。
回到軟件研發領域,你會發現類似上面醫院這種不合理的排隊現象隨處可見,比如軟件缺陷的流轉,軟件需求的實現與交付,軟件制品包發布等待等等。這些也是研發效能提升需要重點關注的領域,需要從全局理清楚全流程,識別出等待浪費的時間,通過流程再造與優化實現全局效率提升。
第三條是“用戶獲益“。對于研效提升,有一點我們必須牢記,那就是成功的標準不是研發效能平臺的成功,而是客戶成功。只有客戶獲益才是檢驗研效項目成功的唯一標準。這里我談以下三點:
偽需求:偽需求是指研效團隊自己臆想出來的,是屬于典型的“手里拿著錘子,看什么都像釘子”的典型案例。那么如何識別偽需求呢?識別標準其實很簡單,就看客戶是不是愿意和你分攤成本,如果業務線已經開始做了,或者想要開始做,那就說明那是業務線的剛需,如果研效平臺能幫助提供方案,那研效平臺的接入就是水到渠成的事情。我就見到過很多這類剛需的例子,比如微服務架構下集成測試環境的搭建就是其中的典型。?
結構問題:著名商業顧問劉潤說過“結構不對,什么都不對“。比如兩個和尚分粥的故事想必大家都聽過,一碗粥兩個和尚要均分,但是分粥的和尚總想多喝點粥,那怎么才能做到無監管情況下的公平呢?教育分粥的和尚說出家人“以少吃為懷”嗎,顯然一旦沒有了監管,他就會給自己多分點,解決這個問題的最好辦法就是一個和尚分粥,另一個和尚選粥,那么這個體制就決定了分粥的均勻性。所以好的策略是承認每個人都是自私的,但是你的策略能夠在人人都是自私的基礎上獲得全局利益的最大化,如果你的全局利益最大化是建立在要求每個人都是大公無私的,那就是失敗的設計,因為這必然會導致失敗?;氐窖行嵘@個問題上,我們必須抱著”不是我們的研效平臺有多好,而是業務線用了以后有什么提升“來定位自己,才能從結構上獲得成功的籌碼。
服務意識:理解了上面的觀點,理解服務意識就很自然了。在研效平臺落地過程中我們需要和業務線互助實現雙贏,業務線收獲現成可用的方案,研效平臺收獲最佳實踐的沉淀,這些最佳實踐的沉淀是至關重要的,為后期的批量成功復制提供了技術基礎。
另外還有一個小經驗可以和大家分享,有時候為了讓研效平臺盡快能夠在業務線落地,讓業務線愿意成為我們的研效平臺的試驗田,我們有時還必須能承擔起主動背鍋的義務,這點如果大家感興趣也可以和我私下交流。
持續改進是研效平臺自身發展的必經之路。很多問題的解決在一開始的時候,我們關注的是如何快速簡單地解決問題,但是當規模起來之后,我們還更需要關注解決方案的普適性和通用性。如果一開始就試圖尋找完美方案,必然會讓得不償失。
這里舉個具體的例子,比如我們需要在Jenkins中通過hook機制去觸發一些操作(比如代碼靜態掃描,單元測試等),最簡單的做法就是在hook中實現操作的具體步驟,這種實現在一開始效率很高,也非常容易實現,但卻不是最優的方案,因為hook中的代碼只會被執行一次,而且hook越來越多以后,各種實現都散落在各個地方,難以維護,同時但凡有新的需要(比如要加入慢SQL掃描),都需要改hook實現,而且這種做法也違背了IaC(Infrastructure as Code)原則。
更好的做法是引入研發效能的消息中心(MQ)通過下游操作的訂閱模式來實現未來的可擴展性。但是如果你從一開始就是建MQ,實現的難度和成本都會大增,業務線有可能就等不及你的方案,從而研效提升就無法如期落地。所以我的觀點是研效落地可以遵循“先圈地,后改進“的策略。
這頁Slides說的是研發效能提升的落地,光靠自下往上和光靠自上往下都是行不通的,而是應該雙管齊下,兩邊從中間擠才是切實可行的方案,由于篇幅原因,這里就不詳細展開了。
這里我提出來兩個概念:“唱戲的“和”搭臺的“。剛開始做研發效能的時候,我們既是搭臺的又是唱戲的,在研效平臺(搭臺)的基礎上提供各業務線的解決方案(唱戲),但是當業務線接入規模不斷擴大的時候,各個垂直領域的多樣化需求越來越多,此時我們已經很難應對各家的個性化非通用需求了(每家要唱的戲都不同),所以此時研效平臺的開放能力就成為了關鍵,研效平臺的建設必須能夠應對這種多樣性,研效平臺的職責轉變成搭建規范的平臺,讓業務線能夠在此平臺上實現各自的個性化需求,所以研效平臺本身的技術架構設計必須考慮可擴展性和靈活性。
?舉個例子,平臺就是Jenkins,靈活性就是上面各種plugin。
掩耳盜鈴是我們在落地研效過程中經常會犯的錯誤。上圖給出了研發效能的“最差實踐“,你可以心里默默數數被砸中幾條。
另一種掩耳盜鈴的例子是普遍采用虛榮性指標來做度量效能。那到底什么是虛榮性指標呢?虛榮性指標是指那些不能直接用來指導后續行動的指標,我們需要的是可以指導我們行動的可執行指標。這么說還是比較抽象,我舉幾個例子你就很容易明白了。?
“接入Sonar的工程數“就是虛榮性指標,與之對應的可執行指標是” Sonar問題的增長趨勢“和” Sonar問題的修復時長“;
“系統用戶數“就是虛榮性指標,與之對應的可執行指標是” DAU單日活躍用戶數“和” MAU月活躍用戶數“;
“接入研效平臺的項目數“就是虛榮性指標,與之對應的可執行指標是”百分之多少的項目使用過研效平臺來完成開發測試和發布流程的;
我們需要的是雪中送炭,而不是錦上添花。
最后一點大家都容易理解“做自己研效平臺的第一個用戶“,研效平臺本身的研發必須通過自己的平臺走,這樣才能站在用戶的角度看待自己的方案,才能和業務線用戶”共情“。
最后是對研發效能行業未來發展方向的展望,由于篇幅原因就不再一一展開闡述了,我后續計劃會專門寫篇文章來談談這塊的內容,敬請期待吧!?
推薦一些衍生閱讀,其中《測試工程師全棧技術進階與實踐》和《高效自動化測試平臺設計與開發實戰》分別是我2019年和2020年寫的書,主要關注在軟件測試效能的提升上,同時也推薦朱少民教授的《全程軟件測試(第3版)》。
預熱一下我和吳駿龍老師正在寫的《軟件研發效能提升之美》,如果一切順利會在2021年和大家見面。
后臺回復關鍵詞【GIAC】可獲取本次大會嘉賓PPT。
總結
以上是生活随笔為你收集整理的研发效能提升最佳实践的探索的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 七夕用腾讯最热门五大编程语言写三行情书
- 下一篇: 「递归」第8集 | 当敲代码的手开始写歌