對於開發人員來說,我們每天都在用技術。但你要知道,我們寫的代碼,其實只是系統的一小部分,我們了解的技術,也只是系統用到的一小部分。要深入掌握技術架構,我們就需要了解整體的系統。
面對一個複雜的系統,我想你可能經常會有以下困擾:
- 不清楚系統整體的處理過程,當系統出問題時,不知道如何有針對性地去排查問題。
- 系統設計時,經常忽視非業務性功能的需求,也不清楚如何實現這些目標,經常是付出慘痛的教訓後,才去亡羊補牢。
不知你是否還記得,在之前的文章中,我已經說過,技術架構是從物理層面定義系統,並保障系統的穩定運行。那麼今天,我會先分析下系統在物理上由哪些部分組成,讓你可以從全局的角度看一個系統;然後再和你一起討論,技術架構會面臨哪些軟硬件的挑戰,以及它都有哪些目標,讓你能夠深入地了解技術架構。
系統的物理模型
對於大部分開發人員來說,我們主要的工作是寫業務相關的代碼,保證業務邏輯正確、業務數據準確,然後,這些業務代碼經過打包部署後,變成實際可運行的應用。但我們寫的代碼只是系統的冰山一角,為了保證應用能正常運行,我們需要從端到端系統的角度進行分析。
我們先看下一個系統的具體組成,這裡我為你提供了一個簡化的系統物理模型,你可以了解一個系統大致包含哪些部分。

從用戶請求的處理過程來看,系統主要包括五大部分。
首先是接入系統,它負責接收用戶的請求,然後把用戶的請求分發到某個 Web 服務器進行處理,接入系統主要包括 DNS 域名解析、負載均衡、Web 服務器這些組件。
接下來,Web 服務器會把請求交給應用系統進行處理。一般來說,我們是基於某個開發框架來開發應用的,比如 Java 應用一般是基於 Spring MVC 框架。
這個時候,開發框架首先會介入請求的處理,比如對 HTTP 協議進行解析,然後根據請求的 URL 和業務參數,轉給我們寫的業務方法。接下來,我們的應用代碼,會調用開發語言提供的庫和各種第三方的庫,比如 JDK 和 Log4j,一起完成業務邏輯處理。在這裡,我們會把開發框架、應用代碼,還有這些庫打包在一起,組成一個應用系統,作為獨立的進程在Web 服務器中進行部署和運行。
到這裡,整個系統要做的事情就完了嗎?
還沒有呢,在我們的應用系統底下,還有基礎平台,它由好幾個部分組成:首先是各個語言的運行時,比如說 JVM;然後是容器或虛擬機;下面還有操作系統;最底下就是硬件和網絡。
接入系統、應用系統、基礎平台就構成一個最簡單的系統。
在大多數情況下,應用系統還要藉助大量外部的中間件來實現功能和落地數據,比如數據庫、緩存、消息隊列,以及 RPC 通訊框架等等。這裡,我統稱它們為核心組件,它們也是系統不可缺少的一部分。
除此之外,還有大量周邊的支撐系統在支持應用的正常運行,包括日誌系統、配置系統,還有大量的運維繫統,它們提供監控、安全、資源調度等功能,它們和核心組件的區別是,這些系統一般不參與實際的用戶請求處理,但它們在背後默默保障系統的正常運行。
到這裡,你可以發現,一個端到端的系統是非常複雜的,它包含了大量的軟硬件。為了保障我們的應用代碼能夠正常運行,我們就需要保證這裡的每個組件不出問題,否則一旦組件出問題,很可能就導致系統整體的不可用。
技術架構的挑戰
應用代碼怎麼組織(比如模塊劃分和服務分層),那主要是業務架構的事,這部分在前面我們已經討論過很多了;而技術架構的職責,首先是負責系統所有組件的技術選型,然後確保這些組件可以正常運行。
我們知道,系統是由硬件和軟件組成的。接下來,我們就分別從軟硬件的角度來看下,技術架構都會面臨什麼挑戰,我們需要如何應對。
硬件的問題
硬件是一個系統最基礎的部分,負責真正幹活的,但它有兩方面的問題。
首先是硬件的處理能力有限。對於服務器來說,它的 CPU 頻率、內存容量、磁盤速度等等都是有限的。雖然說按照摩爾定律,隨着製造工藝的發展,大概每隔 18 個月,硬件的性能
可以提升一倍,但還是趕不上快速增長的系統處理能力的要求,特別是目前許多互聯網平台,面向的都是海量的 C 端用戶,對系統處理能力的要求可以說是沒有上限的。
從技術架構的角度,提升硬件的處理能力一般有兩種方式。
Scale Up
也就是垂直擴展,簡單地說就是通過升級硬件來提升處理能力。CPU 不夠快,升級內核數量;內存不夠多,升級容量;網絡帶寬不夠,升級帶寬。所以說,Scale Up 實際上是提升硬件的質量。
Scale Out
也就是水平擴展,通過增加機器數量來提升處理能力。一台機器不夠,就增加到 2 台、4台,以及更多,通過大量廉價設備的疊加,增強系統整體的處理能力。所以說,Scale Out是提升硬件的數量。
垂直擴展是最簡單的方式,對系統來說,它看到的是一個性能更強的組件,技術架構上不需要任何改造。如果碰到性能有問題,垂直擴展是我們的首選,但它有物理上的瓶頸或成本的問題。受硬件的物理限制,機器的性能是有天花板的;或者有時候,硬件超出了主流的配置,它的成本會指數級增長,導致我們無法承受。
水平擴展通過硬件數量彌補性能問題,理論上可以應對所有服務器處理能力不足的情況,並實現系統處理能力和硬件成本保持一個線性增長的關係。
但水平擴展對於系統來說,它看到的是多個組件,比如說多台 Web 服務器。如何有效地管理大量的機器,一方面,使得性能上可以實現類似 1+1=2 的效果;另一方面,要讓系統各個部分能夠有效地銜接起來,穩定地運行,這不是一件容易的事情。我們需要通過很複雜的技術架構設計來保障,比如說,通過額外的負載均衡,來支持多台 Web 服務器並行工作。
硬件的第二個問題是,硬件不是 100% 的可靠,它本身也會出問題。
比如說,服務器斷電了,網絡電纜被挖斷了,甚至是各種自然災害導致機房整體不可用。尤其是一個大型系統,服務器規模很大,網絡很複雜,一旦某個節點出問題,整個系統都可能受影響,所以,機器數量變多,也放大了系統出故障的概率,導致系統整體的可用性變差。我們在做技術架構設計時,就要充分考慮各種硬件故障的可能性,做好應對方案。比如說針對自然災害,系統做異地多機房部署。
軟件的問題
接下來我們說下軟件的問題,這裡的軟件,主要說的是各種中間件和系統級軟件,它們配合我們的應用代碼一起工作。
軟件是硬件的延伸,它主要是解決硬件的各種問題,軟件通過進一步封裝,給系統帶來了兩大好處。
- 首先是彌補了硬件的缺陷。比如 Redis 集群,通過數據分片,解決了單台服務器內存和帶寬的瓶頸問題,實現服務器處理能力的水平擴展;通過數據多副本和故障節點轉移,解決了單台服務器故障導致的可用性問題。
- 其次,封裝讓我們可以更高效地訪問系統資源。比如說,數據庫是對文件系統的加強,使數據的存取更高效;緩存是對數據庫的加強,使熱點數據的訪問更高效。
但軟件在填硬件的各種坑的同時,也給系統挖了新的坑。舉個例子,Redis 集群的多節點,它解決了單節點處理能力問題,但同時也帶來了新的問題,比如節點內部的網絡有問題(即網絡分區現象),集群的可用性就有問題;Redis 數據的多副本,它解決了單台服務器故障帶來的可用性問題,但同時也帶來了數據的一致性問題。
我們知道,分佈式系統有個典型的 CAP 理論,C 代表系統內部的數據一致性,A 代碼系統的可用性,P 代表節點之間的網絡是否允許出問題,我們在這三者裏面只能選擇兩個。對於一個分佈式系統來說,網絡出問題是比較常見的,所以我們首先要選擇 P,這意味着我們在剩下的 C 和 A 之間只能選擇一個。
CAP 理論只是針對一個小的數據型的分佈式系統,如果放大到整個業務系統,C 和 A 的選擇就更加複雜了。
比如有時候,我們直接對訂單進行寫庫,這是傾向於保證數據一致性 C,但如果數據庫故障或者流量太大,寫入不成功,導致當前的業務功能失敗,也就是系統的可用性 A 產生了問題。如果我們不直接落庫,先發訂單數據到消息系統,再由消費者接收消息進行落庫,這樣
即使單量很大或數據庫有問題,最終訂單還是可以落地,不影響當前的下單功能,保證了系統的可用性,但可能不同地方(比如緩存和數據庫)的訂單數據就有一致性的問題。
魚和熊掌不能兼得,系統無法同時滿足 CAP 的要求,我們就需要結合具體的業務場景,識別最突出的挑戰,然後選擇合適的組件,並以合理的方式去使用它們,最終保障系統的穩定運行,不產生大的業務問題。
技術架構的目標
好,現在你已經了解了系統的複雜性和軟硬件的問題,那技術架構就要選擇和組合各種軟硬件,再結合我們開發的應用代碼,來解決系統非功能性需求。
什麼是系統非功能性需求呢?這是相對於業務需求來說的,所謂的業務需求就是保證業務邏輯正確,數據準確。比如一個訂單,我們要保證訂單各項數據是準確的,訂單優惠和金額計算邏輯是正確的。而一個訂單頁面打開需要多少時間,頁面是不是每次都能打開,這些就和具體的業務邏輯沒有關係,屬於系統非功能性需求的範疇。產品經理在一般情況下,也不會明確提這些需求。非功能性需求,有時候我們也稱之為系統級功能,和業務功能相區分。
那對於一個系統來說,技術架構都要解決哪些非功能性需求呢?
系統的高可用
可用性的衡量標準是,系統正常工作的時間除以總體時間,通常用幾個 9 來表示,比如 3個 9 表示系統在 99.9% 的時間內可用,4 個 9 表示 99.99% 的時間內可用,這裡的正常工作表示系統可以在相對合理的時間內返回預計的結果。
導致系統可用性出問題,一般是兩種情況:
- 一種是軟硬件本身有故障,比如機器斷電,網絡不通。這要求我們要麼及時解決當前節點的故障問題,要麼做故障轉移,讓備份系統快速頂上。
- 還有一種是高並發引起的系統處理能力的不足,軟硬件系統經常在處理能力不足時,直接癱瘓掉,比如 CPU 100% 的時候,整個系統完全不工作。這要求我們要麼提升處理能力,比如採取水平擴展、緩存等措施;要麼把流量控制在系統能處理的水平,比如採取限流、降級等措施。
系統的高性能
我們這裡說的高性能,並不是指系統的絕對性能要多高,而是系統要提供合理的性能。比如說,我們要保證前端頁面可以在 3s 內打開,這樣用戶體驗比較好。
保證合理的性能分兩種情況:
- 一種是常規的流量進來,但系統內部處理比較複雜,我們就需要運用技術手段進行優化。比如針對海量商品的檢索,我們就需要構建複雜的搜索系統來支持。
- 第二種是高並發的流量進來,系統仍舊需要在合理的時間內提供響應,這就更強調我們做架構設計時,要保證系統的處理能力能夠整體上做水平擴展,而不僅僅是對某個節點做絕對的性能優化,因為流量的提升是很難準確預計的。
系統的可伸縮和低成本
系統的業務量在不同的時間點,有高峰有低谷,比如餐飲行業有午高峰和晚高峰,還有電商的大促場景。我們的架構設計要保證系統在業務高峰時,要能快速地增加資源來提升系統處理能力;反之,當業務低谷時,可以快速地減少系統資源,保證系統的低成本。
高可用、高性能、可伸縮和低成本,這些技術架構的目標不是孤立的,相互之間有關聯,比如說有大流量請求進來,如果系統有很好的伸縮能力,它就能通過水平擴展的方式,保證系統有高性能,同時也實現了系統的高可用。如果系統的處理能力無法快速提升,無法保證高性能,那我們還是可以通過限流、降級等措施,保證核心系統的高可用。
我在前面也提到,這些目標很多時候會衝突,或者只能部分實現,我們在做技術架構設計時,不能不顧一切地要求達到所有目標,而是要根據業務特點,選擇最關鍵的目標予以實現。
比如說,一個新聞閱讀系統,它和訂單、錢沒有關係,即使短時間不可用,對用戶影響也不大。但在出現熱點新聞時,系統要能支持高並發的用戶請求。因此,這裡的設計,主要是考慮滿足高性能,而不用太過於追求 4 個 9 或 5 個 9 的可用性。
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/259178.html