百萬年薪架構師之路:談應用系統架構設計

程式設計師北哥發表於2020-11-09

​北哥在前文陸續總結了程式設計師成長所具備的核心能力,以及Java程式設計師成長過程中應學習的基礎知識。在一個Java程式設計師工作3、5年之後,已經可以承擔起大部分的核心開發工作,成長為團隊中的高階開發人員。大部分工作中遇到的問題都已經可以自行解決。這個階段很多同學會面臨著新的成長困惑,到底接下來自己還需要在哪些方面繼續提升?如何能夠成長為團隊裡面的架構師呢?百萬年薪架構師之路:談應用系統架構設計

市面上有很多分析和拆解架構師能力的書籍,例如《聊聊架構》《億級流量網站架構核心技術》《大型網站技術架構:核心原理與案例分析》等,書中有一些相關的實戰和理論知識分享。這些書籍如果有時間推薦大家去讀一讀。

今天北哥結合自己工作中的經驗,也來淺談一下如何做應用系統架構設計。

需要說明的是,架構師本身要求的是綜合能力,架構也分為業務架構、應用系統架構、技術架構、資料架構等多個維度多個細分領域,但今天分享的關於架構的相關內容,更多還是側重在服務端的應用系統架構。

01 指導思想

作為一個架構師,在做應用系統架構時,最好逐步沉澱自己的一套指導思想,指導思想用於在做架構設計過程中遇到困惑或遇事不決時的一個指引。我個人總結下來的經驗有以下三點

  • 平衡和取捨

架構是一個複雜的工作,既要考慮當下的需求,還要關注未來可能的變化;既要考慮的足夠全面,還要簡單容易實現;既要衡量實現成本,還要關注落地的效率。這些無不意味著在做架構時需做好平衡,學會取捨。

  • 迭代和演進

一個好的架構,一定是經過長期迭代演進而來的。在做架構設計時,受限於當前已經明確的需求,往往無法對未來考慮的那麼全面。即使在做架構設計時已經考慮到了方方面面,系統上線後也會遇到一些新的未知問題,並且隨著需求的不斷迭代,又會引入新的變化和挑戰,因此持續的對架構做優化和迭代演進,是必須要重視的。

  • 聚焦業務需求

沒有毫無瑕疵完美的架構,也沒有一成不變適合所有業務的架構,只有適合當前業務和產品需求的架構。我們可以借鑑、吸收別人的經驗和實踐總結,但最合適的架構一定是結合業務的實際需求設計和演變出來的。脫離業務需求設計的架構一定會在開發中遇到新的問題。

百萬年薪架構師之路:談應用系統架構設計

02 架構設計目標

在做應用系統架構設計時,應遵循一些普適的架構設計目標。這些目標包括

  • 可實現的:架構被設計出來,一定是需要能夠被實現和落地的,如果設計架構所採用的技術還沒成熟或不具備生產環境可用性,這種架構只能停留在理論階段,不具備落地的可行性,這樣的架構也就沒有特別大的價值和意義。
  • 可擴充套件的:雖然無法預知需求未來的變化,但有些場景下,我們設計的架構也應該具備當使用者量、頻寬、資料量等增長時,具備較好的擴充套件性;除此之外,在做需求分析時,把系統、領域服務甚至模組做好規劃和設計,能夠合理的應對未來需求膨脹可能帶來的問題,也是架構可擴充套件性的一種體現。
  • 高可用的:系統架構需要考慮各種異常情況下系統可用性,如流量的突然爆發的消峰限流,某個服務或介面故障後的降級等,通過在架構中設計的各種措施保障整個應用系統是高可用的。
  • 可衡量的:應用系統架構設計最終都需要落地到程式碼層面實現,提供出可線上釋出的系統和服務。我們在做系統架構設計時,需要根據業務資料的預估,設計出滿足一定量級的系統資料指標,將架構設計的結果量化。在遇到系統負載過高需要擴容時,就可以參考定量的資料指標預估出所需的伺服器和資源等。

接下來從業務需求分析開始,到最終系統上線運營,按照不同階段需要關注的知識和內容,來說明整個應用系統架構設計過程需要考慮的問題。百萬年薪架構師之路:談應用系統架構設計

03 需求分析階段

正如前文所述,系統架構應該是聚焦業務需求的,業務需求分析,是做系統架構設計的必要前置。這裡簡述下我在需求分析階段工作的大致思路。正常情況下,進入到架構師層面的需求,都經過了業務人員和產品人員至少一輪的討論溝通,或已經有基本的業務和產品需求雛形,或已經產出業務的MRD(業務需求說明書)或產品的PRD(產品需求說明書)。這時架構師進入後需要再和業務及產品同學進行充分的討論溝通,明確和產出以下幾點資訊:

  1. 確定清楚業務目標,搞清楚業務需要解決的核心問題是什麼,通過產品和系統期望帶來的效果是怎樣的。
  2. 進行業務流程梳理和業務建模。業務建模的核心在於梳理清楚使用者角色、業務場景、流程和相關規則策略。弄清楚不同使用者角色在哪些場景下可以進行什麼樣的操作,由此對業務有更清晰的全域性認識。
  3. 根據業務模型、業務產出的MRD或產品產出的PRD,整理出大概的子系統和功能列表。功能列表先從第一層級梳理,再層層細化,一般以不超過四層為宜。如第一層級分為使用者管理、訂單管理、售後退換貨管理等。第二層級中使用者管理再細分為註冊登陸,基礎資料維護、禁用啟用等,依次類推。
  4. 根據業務模型和功能列表,預估和完善非功能性需求,如對總使用者量、同時線上使用者量、系統訪問量等非功能需求,系統效能、響應時間、qps等系統效能要求,系統工期、人員投入、專案組織結構、其它成本等專案約束條件等。在需求分析階段,我會最終產出一份基於業務模型拆解出的功能需求列表和非功能需求列表。這將作為後續應用系統架構的核心參考和依據。

百萬年薪架構師之路:談應用系統架構設計

04 架構設計階段

在需求分析階段完成後,就進入到系統架構設計階段。

在系統架構設計階段,我一般會首先做資料建模。根據業務模型和功能列表,已經可以分清楚大概的系統、模組和功能,由此資料庫的概念模型基本能夠確定下來。通過資料庫的概念模型設計,結合需求分析階段產出的功能需求列表,整個系統的詳細需求基本可以被印在大腦中了。同時經過概念模型的設計,不同資料實體之間的關係已經相對清晰,服務或領域的劃分也具備初步的雛形了。完成資料庫的概念模型後,開始進行詳細的系統架構設計和技術選型階段。

在系統架構設計階段,我會按照分層架構設計的思想,逐步做細化展開。在目前的主流技術方案中,前後端分離基本上是預設的標準,核心原因一方面是前後端技術演進快速發展,技術專業人員分工更明確;另一方面當前的產品開始移動化,前後端一體的架構無法支撐當前移動端特別是App類應用的開發,前後端分離也成為不得不為之的舉措。

按照分層架構設計的思想,將整個架構分為前端接入層、服務層、資料訪問層、資料儲存層。在部分高併發的系統中,還會有快取相關技術貫穿在整個架構層級之間。

前端接入層

首先,在前端接入層,主要解決使用者流量從終端發起請求到被應用伺服器接收之前這一段的問題。

在前端接入層,核心需要解決終端展現時的響應速度和穩定性。

在傳統的PC網際網路場景下,大部分產品和應用以瀏覽器為終端,通過網頁的方式展現在使用者面前,如京東、淘寶等電商類的網頁版。在終端層面,因為使用者請求量巨大,會藉助頁面靜態化、CDN等方式,提升頁面載入速度。在請求層面,為了提升穩定性和應對更大的流量挑戰,在流量進入到應用伺服器前,會通過使用DNS、軟硬體負載的方式進行流量分流,將請求打到不同的應用伺服器上。這裡會使用到的硬體負載有F5等,而軟體負載主要通過nginx實現,早期還有LVS、Haproxy的方案等。

服務層

說完接入層,再來看服務層。服務是應用系統的核心,承擔著業務和產品核心需求和邏輯的實現。

在服務層,需要解決的重點問題問題是,服務是否可以靈活快速的水平擴充套件,以應對未來系統可能的訪問量劇增。

為解決這個問題,需要對是否進行分散式架構設計進行權衡。分散式架構設計的核心是通過對服務的解耦,來解決應用的水平擴充套件問題,降低單服務單機器的壓力。如果系統所需要承擔的流量在可預期的未來會有較大的增長,分散式架構設計就是有必要的。而如果系統流量在很長一段時間內都相對有限且平穩,則分散式架構就顯得沒那麼必要。這裡即需要做好平衡和取捨。

分散式架構雖然能夠帶來服務水平擴充套件的便捷性,以應對未來可能的系統流量大幅增長,但需要付出較大的系統維護成本。如果選擇暫時不採用分散式架構,服務層也同樣可以在工程層面,按照服務的介面層、服務的邏輯層和服務的資料層進行劃分模組和子模組,然後在程式碼構建打包時整合到一個單體應用作為一個jar或war包一起釋出。根據我之前的經驗,在一個業務和產品的早期階段,採用模組化劃分的單體應用方式的架構,可以快速完成產品MVP版本的上線試錯,當業務發展到一定規模後再啟動分散式架構的服務化改造,也不失為一個較好的選擇。

無論在一開始就選定分散式架構方案,還是在後期做分散式架構的服務化改造時,都會面臨著另外一個選型問題:到底是採用分散式服務還是微服務方式來構建應用。

分散式服務和微服務是在分散式架構演進過程中產生的不同概念,按照我的理解,分散式服務關注的重點是分散式,重點解決服務的壓力負載分擔,而微服務重點關注的是服務的單元顆粒度大小,更關注服務的原子性、獨立性。二者都是為了解耦合,但在解耦合的顆粒度上稍有不同。具體的選擇也需要根據應用系統的規模、領域劃分等綜合考量。

落地到分散式服務的架構技術選型上,有以傳統的RPC框架為主導的技術體系,和以Spring Boot微服務框架為基礎的Spring Cloud全家桶。

傳統的RPC框架以早期阿里開源的Dubbo框架為代表,核心的實現是基於動態代理+反射的方式來實現服務之間的介面通訊,服務和服務之間的底層呼叫是基於socket來實現資料傳輸互動的。而Spring Cloud全家桶,核心是基於Http協議實現的一套微服務框架,服務和服務之間的呼叫是通過Http介面實現互動的的。相比Spring Cloud,RPC框架一般具有可自定義資料結構、網路傳輸速度快、效率高等特點,而Spring Cloud因為是基於Http協議進行網路傳輸,訊息的包體大小受Http協議限制做了封裝顯得相對臃腫,在網路傳輸時效率相對低一些,但Spring Cloud因有一整套元件和生態的支撐,因此在不做過多效能苛求的情況下,也是目前可以快速採用的方案之一。另外一種將二者結合的方案,利用Spring Cloud設計和實現介面的接入閘道器,再通過閘道器將請求轉發到RPC服務中,則是目前一些大型應用普遍採用的方案。

在使用Spring Cloud或RPC框架的過程中,另外一個需要關注的問題是服務之間的耦合問題。雖然分散式服務或微服務本身就是為了解決耦合問題,但應用和應用、服務與服務之間的依賴關係並不因為使用Spring Cloud或RPC框架就消失了,在一些場景下,適度的服務之間的依賴是允許且必要的,但過度的服務之間依賴,甚至發展成服務與服務之間相互依賴,就是需要避免的一種情況了。通過訊息中介軟體,將原本有上下游關係的依賴,通過訊息解耦,從而讓服務和服務之間避免強依賴,是其中的一個解決方案。常用的訊息中介軟體有RabbitMQ、RocketMQ、Kafka等。

資料訪問層
說完服務層,再來看資料訪問層。所有的應用都離不開資料,資料是一個系統的靈魂所在。資料訪問層主要用於完成服務層和資料儲存層之間資料的互動。因為資料儲存方式的多樣性,資料訪問層一個重要功能是實現對不同資料儲存方式的封裝,儘量做到對服務層遮蔽具體的資料儲存細節。另一個資料訪問層的重要作用,是解決資料儲存場景下的資源管理問題,包括連線池資源、分庫分表、讀寫分離等。具體是否需要做分庫分表、讀寫分離等,需要根據應用的實際資料量大小、選擇的資料儲存方式等做綜合考量。

資料儲存層

最後,再來考慮資料儲存層的搭建和選型。

資料儲存層是用於將具體應用產生的資料持久化。不同的資料儲存方式適用的業務場景也有很大不同。如對事務要比較高,一般採用關係型資料庫如Mysql、Oracle等;對資料結構和表結構擴充套件性要求較靈活的可以採用NoSQL資料庫如MongoDB、CouchDB等;如果需要儲存的資料量非常龐大,可以選擇目前基於hdfs的儲存方案如Hbase、Hive等;還會有對檔案、圖片等有儲存需求的,可以採用分散式檔案儲存或雲端儲存的方式等。資料儲存的方案本身沒有好壞之分,具體還是要分析業務的實際需求來做平衡和選擇。

關於快取

除了以上所述的幾個層級,在大部分網際網路應用中,當系統訪問使用者量達到一定量級,或QPS較高的場景下,還會通過增加快取來降低系統和介面的響應時間,提升系統的效能。常用的快取框架有Redis、Memcache等。在架構設計階段,我們把整個系統按照分層的思想做拆解說明,根據業務的實際需求,對各層中採用的技術和方案做平衡和取捨。架構設計階段完成並不意味著整個應用系統架構的完成。接下來需要將架構設計落地到程式碼中。百萬年薪架構師之路:談應用系統架構設計

 

05 編碼階段

在架構設計方案完成後,對於開發工程師來說,已經可以根據架構設計方案來指導進行詳細需求設計和編碼。對於架構師來說,在這個階段需要重點關注的有以下幾點:

  • 工程結構:良好的工程結構,可以大幅降低後續程式碼的維護成本和大團隊的協作成本。每一層的工程結構也會有所側重和不同,我們可以在平時沉澱適合自己企業的工程結構腳手架,在需要時一鍵建立,既能提升效率,還可以統一工程模板。

  • 設計模式:針對複雜的需求,架構師需要重點關注,將不同設計模式組合、擴充套件應用到程式碼設計中,提升程式碼的可擴充套件性和可維護性。

  • 程式碼模板:程式碼模板可以統一程式碼風格,提升程式碼的可讀性和可維護性。

  • 程式碼檢查:通過對程式碼的檢查,發現不合理的程式碼組織和設計、潛在的程式碼隱患等等。也可以藉助一些第三方外掛或工具如PMD、Findbugs等輔助做檢查。


百萬年薪架構師之路:談應用系統架構設計

06 上線運營階段

一個好的架構,一定是需要經歷線上系統的檢驗的。在測試人員完成質量測試後,需要對應用系統做上線釋出,進入到上線運營階段。

在上線運營階段,架構師核心職責是做好各項監控和告警指標的設定。

在監控層面,首選需要對應用系統相關的各項效能指標做監控。通過一些開源或企業自研的監控工具,需要對應用系統所採用的物理資源如磁碟、記憶體、CPU、網路等進行監控;需要對資料儲存元件如資料庫的慢查詢、I/O、庫大小等進行監控;對中介軟體如RabbitMQ、Redis等讀寫、容量等進行監控;對應用系統效能如介面響應時長、95線、99線的監控等等。

另外一個重要的監控物件是業務指標的監控,如一段時間內的登陸使用者量、簡訊傳送量、訂單下單量、訂單支付量等等。業務指標的監控往往能反映出一些系統層面的異常,引導去追究引起業務指標異常的根本原因,從而提升系統的可靠性和穩定性。

具體建立哪些監控指標需要根據不同的監控物件進行合理的設定。

建立完監控指標後,還需要建立告警體系,將異常的指標及時告警通知出來。一般的監控系統都會有提供類似簡訊、釘釘等告警方式的接入。

最後,在上線運營階段還需要收集和關注系統的日誌,及時排查修復異常,保障系統的穩健執行。百萬年薪架構師之路:談應用系統架構設計


以上是從一個業務的需求階段開始,到整個業務的應用系統上線運營,作為一個架構師需要關注的方方面面。

當然,其中的每一個架構點和技術方案,展開來看都是一個很大的課題。當你具備架構的全域性思維之後,接下來就可以深入到不同領域專研,並在工作中不斷實踐和試錯,最終完成自身技能的進階。

自計算機誕生以來,各項軟硬體技術即在不斷迭代更新,催生著軟體架構的不斷升級換代。而隨著大資料雲端計算5G時代的帶領,新的業務場景如音視訊、直播、物聯網等等業務挑戰也會隨之而來,我們對架構的追求也永無止境。

希望你我都可以在持續的架構演進中,不斷學習,持續進步。

相關閱讀

一個Java程式設計師成長之路

聊聊程式設計師的核心能力

 

·END·

 

相關文章