編者按:本文來自微信公眾號“雲原生計算”(ID:gh_94389f45059d),作者:鄭同學,36氪經授權發佈。
自從2009年入職百度以來,已經經歷了11年了,我自己從一線研發工程師開始,也逐步成長成為了帶領複雜技術方向的技術負責人。10年多的工作歷程,讓我有幸經歷了大範圍的技術演變,特別是雲計算和雲原生技術從朦朧到普及,對工程師和架構師的要求也發生了不少變化。趁着自己入職11週年的日子,結合我自己在百度的成長曆程,總結下我認為在雲計算特別是雲原生時代,對軟件架構師的核心能力要求,希望幫助大家在通往架構師的路上少走彎路。
初出茅廬從工程師變成子系統的技術骨幹讀書的時候並不瞭解搜索引擎,一直想着自己要從事一個有深度的技術方向,當時聽説讀到 Google 的三駕馬車的論文非常厲害,趕緊拿過來拜讀。但是受限於技術背景的缺失,對 MapReduce 的理念卻完全不理解。後來無意中讀了一本搜索引擎的入門書籍,一下子被搜索引擎的技術吸引住了。我發現搜索引擎同時涉及工程和算法兩大方向,從底層的 Linux 內核到分佈式系統,從簡單的壓縮算法到複雜的 pagerank ,是足夠我學習一生的技術方向。於是抱着做搜索引擎的信念,開啓了找工作的歷程。隨後有幸收到了百度和阿里的 offer,考慮到百度肯定是搜索領域的領頭羊,放棄了即將成為"阿里雲"的公司,選擇了百度。
剛入職的時候我被分配到搜索工程團隊,第一個項目是基於 Hadoop 重構原來的偽分佈式架構下的建庫系統,來解決偽分佈式架構的不可線性擴展的問題。當時百度的索引數據量增長非常快,急需 MapReduce 這樣劃時代意義的架構來解決。我也是這時候加入了這個團隊,經過3年多的時間,我和小夥伴一起把建庫系統從偽分佈式架構,升級成 MapReduce 架構,再基於 MapReduce 架構優化成了流批結合的流式建庫架構,建庫的效率提升了數十倍以上。我自己也從一線工程師逐步成長成小方向的核心骨幹。這個階段我認為主要鍛鍊了下面3項核心能力:
(一)軟件工程的持續改進能力軟件研發是團隊作戰,我們每個工程師都是研發環節的一員。在軟件研發領域,決定團隊研發效率的核心在於研發流程和協作的效率。互聯網行業面臨快速的變化,不確定性非常強,雲原生時代也更倡導的 DevOps 理念和敏捷的研發模式來提升效率,快速試錯,來應對不確定性。我們團隊從2011年開始嘗試從傳統的瀑布模式轉移到敏捷模式,並且選擇 DevOps 工具來幫助我們實施敏捷流程。
下面是我總結的幾點核心能力:
把握關鍵流程:需求分析,產品設計,軟件研發,產品驗收等關鍵環節,需要明確關鍵的角色為此負責,比如需求分析和產品設計必須經過產品負責人的審查,軟件設計,編碼和測試必須經過技術負責人和對應模塊負責人的審查等等。
使用工具自動化:為了提升效率,讓大量重複性高的環節自動化,包括文檔工具,需求卡片的自動化狀態流轉,選擇 IDE 和代碼審查工具,代碼搜索,構建自動化測試流水線和基礎設施等。將重複性高的工作自動化來提升效率,我認為這才是工程師文化的精髓。
重視代碼審查:代碼是軟件研發環節最核心的交付物,也是工程師之間需要協作的關鍵之一。作為架構師需要能夠發現並且持續優化涉及代碼審查的環節,這方面 Google 的代碼審查實踐給我們提供了非常好的參考。
架構師或者技術骨幹需要對研發流程的每個環節保持着敏鋭的嗅覺,能夠及時發現其中的問題,並提出有效的優化方法。我們經常討論架構師要不要寫代碼的問題,在我看來,不管架構師是否動手寫代碼,一定要對研發流程各個環節保持敏感,這樣才能更好的帶領軟件項目高效高質量的落地。
(二)業務需求分析和理解能力理解業務可以讓架構師的架構設計更快的落地,也讓架構師能夠更為順暢的和業務研發同學進行溝通和交流。所以架構師切忌不可脱離業務,尤其是業務線的架構師,要時刻保持對業務的一定程度的理解能力。我們作為搜索架構團隊,就需要經常和算法團隊交流,和他們討論算法團隊的痛點和他們的發展預期,提前在工程架構上做好準備工作。
理解業務:技術的核心是為了讓業務獲得成功,架構是技術的核心之一,所以架構師一定要加強對業務的深入理解,瞭解業務的痛點,偏向業務的架構師甚至能夠預測業務的發展趨勢,提前在業務需要的技術方向進行適當的準備。比如當時我們決定遷移 MapReduce 架構完全是預測到已有架構完全無法承擔未來的數據增長,需要提前佈局。
提煉需求:很多時候用户提出的需求未必是真正的需求。面對需求,要養成多思考的習慣。思考需求的場景是什麼,思考需求背後需要解決的問題是什麼,來幫助我們識別並解決真正的需求。作為架構團隊,算法和運維同學經常給我們提需求,但是用户提給我們的需求其實是經過自己加工的,隱藏了背後的場景,把他自己設計的解決方案當做需求提給了我們,但是經過深入討論場景之後,往往可以把握真實的需求,設計更好的方法。
隨時業務的發展和技術的演化,我相信任何一家公司或者任何一個代碼模塊,都有所謂的技術債務或者實現的不那麼好的代碼和架構。架構師需要能夠識別那些真正的技術債務或者説技術折中,這就要求架構師能夠把握技術債務的影響程度,讓技術想着持續優化和改進方向演化。
適當的時機意味着把握目標,解決技術債務不是目標是手段,把握好目標才能更有的放矢。比如高頻迭代的模塊,因為結構耦合嚴重影響了效率和新功能的發佈,或者説質量低下,頻繁發生問題等等。或者説架構師在一定程度上預測未來的發展趨勢,讓技術朝着更先進的方式演化。我經常遇到一種情況是看到多種技術選型,架構師總是想所謂的統一架構。並以此為目標,卻忽略了技術背後的真正業務目標,不能真正解決問題。
迭代式的發展可以有效降低技術風險,這個過程要注意避免兩個極端。一個極端是動輒進行大規模的重構,一個項目耗時數人年或者更長時間上線。這種情況不僅項目風險極大,而且也大大減少了試錯的機會。另一個極端是不斷的添磚加瓦,只關注新功能的設計和研發節奏,而不做任何技術債務優化工作。這樣時間久了之後,項目就會越發難以維護,周邊類似項目不勝枚舉。
遊刃有餘從技術骨幹成長為架構師到2012年左右,我對於分佈式建庫系統已經非常熟悉了,大大小小的項目可以説手到擒來。但是我自己還不是十分滿意,一方面我覺得自己只瞭解建庫環節,對搜索引擎的檢索和抓取環節完全沒接觸過,另一方面很多技術方向是在前人的積累上做的,感覺自己原創的並且先進技術比較少,所以我就想參與比較有開創性的之前沒有做過的技術方向。從2013年開始跟着師傅一起探索新的技術方向。我們觀察到不管是離線服務還是在線服務,當時微服務框架和中間件的能力是非常初級的,開源領域也沒有更為成熟的技術,決定自己研發一套先進的微服務系統,現在看起來就是 K8S + ServiceMesh + SpringBoot (C++版) 的組合體。這個技術方向讓我自己一方面對 C++ 底層技術非常熟悉,也讓我認識了當時微服務的思想和技術趨勢。在整個技術方向的研發和業務運用過程中,我自己的能力也得到了更全方面的鍛鍊,從技術骨幹逐步成為負責一個技術方向的架構師。這時候也正好是以 Spring 為核心的微服務技術的快速發展時期。
(四)歸納抽象和技術泛化能力架構設計的本質我認為是抽象和泛化,我在設計微服務框架過程中,不管是對外接口,還是內部組件設計,經過了大量抽象思維模式的訓練。抽象是將共性和差異化的東西分離出來,共性的部分抽象成獨立的接口,功能模塊或者服務。泛化是將技術運用到更多相似的場景,解決相似的問題。抽象和泛化是相輔相成的,需要架構師對問題進行反覆深入的思考和對比,思考問題的背後最本質的東西,解決本質的問題。日常編寫代碼的時候,把握好代碼設計的 SOLID 原則,在需要的時候對代碼或者架構進行局部重構等過程就是鍛鍊抽象能力的好機會。有了代碼級的抽象和泛化能力作為基礎,可以進一步參與模塊級或者子系統級的架構設計工作,更深入的鍛鍊架構設計能力。
抽象和泛化能力的培養需要我們能認清事物的本質,對此我特別推薦大家鍛鍊結構化的思維模式。《金字塔原理》或者《系統化思維導論》等書籍是鍛鍊結構化思維模式的經典書籍,非常詳細的闡述了結構化思維的原理和方法,強烈推薦大家閲讀並且運用到日常工作中。
歷史是一面鏡子,日常工作中及時的總結和覆盤也非常有幫助。在每完成一些階段性工作之後,對自己的工作過程和成果進行總結,可以站在更高的視角看待自己的工作過程,可以幫助自己發現更多的不足並加以改善。
(五)項目管理和技術領導能力隨着自身能力的不斷成長,我也逐步開始擔任技術方向的負責人並且同時進行多個項目了。一方面要帶領整個研發團隊完成多個項目的落地,另一方面要求規劃未來團隊的發展方向。這就要求架構師具備項目管理能力和一定程度的技術領導力,從而帶着整個團隊一起完成工作。項目管理的核心是項目的工作拆解,研發工作的分配和項目進度的追蹤等。項目執行過程中,還要根據具體問題,做出對應的技術判斷和決策。比如研發工作的優先級和依賴關係調整,人力的重新分配,上下游環節的梳理和溝通等。最終保證項目在要求的時間內達到最優的結果。
技術領導力的核心我認為有三個要素:定義目標,結果導向,組織能力。首先是設定目標,目標代表團隊的方向,合理的目標是團隊成功的前提。其次是結果導向,團隊最終為結果負責,不是為技術負責,真正創造了價值才是團隊得以發展的根本。最後是組織能力,良好的組織能力是團隊高效達成目標的保障。這包括充分理解團隊成員的特點,做到知人善用;合理設計協作流程和組織結構,提升協同效率;識別核心崗位和關鍵人才,做到人崗匹配等。管理是一門學問,架構師需要學一些管理方面的知識,才能更好的帶領團隊達成結果。