技術架構的戰略和戰術原則
技術架構,是將產品需求轉變爲技術實現的過程。技術架構解決的問題包括瞭如何進行純技術層面的分層、開發框架選擇、語言選擇(這裏以 JAVA 語言爲主)、涉及到各自非功能性需求的技術點(安全、性能、大數據)。技術架構是確定組成應用系統實際運行的技術組件、技術組件之間的關係,以及部署到硬件的策略。
技術架構面臨最大的挑戰是 “不確定性”。在技術架構上,很多時候就會面臨這種選擇。是要選擇業界最新的技術?還是選擇團隊最熟悉的技術?如果選擇最新的技術,遇到新技術出了問題怎麼解決?如果選擇目前熟悉的技術,後續技術演進怎麼辦?這些都是架構師在做技術架構過程中需要考慮的。
業務在千變萬化、技術在層出不窮,沒有一套通用的技術架構模式來適用所有的系統。那麼,我們如何保證在做技術架構時,能夠實現一個穩定、出色的系統。面對這些 “不確定性” 時的架構設計問題,這裏從戰略和戰術兩個層面來提供一些設計原則。戰略層提供的是技術架構的方法和思路,屬於頂層設計;戰術層提供的是技術架構的技術實踐方式,更偏向詳細設計。
戰略層設計原則
戰略層的設計原則就是:合適原則、簡單原則、演化原則。
1.1 合適原則
技術人員有一種很強的技術情懷,就是在做設計的過程中,很希望挑戰新的技術、在項目中採用最新的框架、或者自己重造一個比業界的還要牛的輪子。這樣才能夠顯示出自己的優秀,以至於不讓自己顯的那麼平庸。比如,在項目中重新造一個能夠解決億萬級數據的新的 xx 流式計算技術,比 flink 還要牛一百倍;有或者在項目中使用最新的 xx 技術,能讓系統承擔億級用戶的訪問。
那麼現實是,如果在設計過程中一味追求新技術,往往失敗的可能性很高。
- 沒有那麼多人,卻想幹那麼多活
現實環境中我們一個業務團隊可能就十幾個人,項目工期短、上線要求快。在這種情況下,如果還要抽調幾個人去研究、搭建、維護新的技術框架,對於項目勢必會造成延期的影響。
- 沒有那麼多積累,卻想一步登天
很多業界領先的方案,不是一幫優秀的開發加在一起,加班加點就能做出來的。而是經過幾年時間的發展才逐步完善和初具規模。如果我們也想自己做一套類似的技術,不是說不可能。我們需要集合當下的技術實力、技術積累,做出適合自己團隊情況的技術評估。
- 沒有最新,只要最合適
所有新的技術剛出來都是打着比舊技術擁有更加出色的性能、提供更加優秀的擴展性。是不是使用新技術,就能解決一切問題了?新技術的出道,勢必是解決某一場景下的問題,並不是一味萬能良藥。只有瞭解清楚每種技術的產生背景,適用場景,才能出一個對自己項目最優的選擇。技術選型沒有最新,只有最合適。
總結一下,合適原則就是適合優於業界領先。
1.2 簡單原則
我們總是希望能將我們的軟件設計的精美、宏大,這樣才能彰顯我們系統的複雜度和難度。我們是不是會遇到這樣的場景,在做設計方案的時候,如果一個解決方案很簡單,而且能很快的滿足需求。在評審方案時,就會有人覺得這個方案是不是太簡單了,沒有什麼技術含量,是不是需要再設計的複雜一點。
系統是不是一定要設計的複雜?在回答這個問題前,我們先看下軟件領域的結構複雜性和邏輯複雜性。
(1)結構複雜性
結構複雜的系統有兩個特點:第一,組成的組件數量很多;第二,這些組件之間的關係很複雜。如下圖:
圖 1
結構上的複雜性存在的第一個問題是,組件越多,就越有可能其中某個組件出現故障,從而導致系統故障。假設組件的故障概率是 1%(有 1% 的時間不可用),那麼 2 個組件的系統可用性是 99%*99%=98%,5 個組件的系統可用性是 99%*99%*99%*99%*99%=95%,兩者相差 3%。說明組件越多,系統穩定性就越差。
結構上的複雜性存在的第二個問題是,某個組件改動,會影響關聯的組件。比如上圖中 C 組件發生改動,會影響 A、B、D,而 A 有會影響 E。這樣就會形成一連串的多比諾效應。
(2)邏輯複雜性
意識到結構複雜性的問題後,只要減少組件就能讓系統結構變簡單?這樣做還是行不通,原因在於除了結構的複雜性,還有邏輯的複雜性,如果一個組件的邏輯太複雜,通用會帶來問題。
我們試想一下,把淘寶的所有功能都在一個組件中實現,可以想象這個系統要有多龐大:幾百人維護一個系統、代碼分支幾十個、需求變更應接不暇、不同分支的迴歸測試、修改一段代碼可能影響整個系統的運行等等。這些場景相信大家都不希望看到的。
總結一下,簡單原則就是大道至簡。
1.3 演化原則
軟件架構和建築架構很多相同的地方,架構這個詞也是從建築領域借鑑過來的。比如,軟件架構描述的是系統的結構、以及各模塊之間的關係。而建築結構描述的是一幢建築的結構,以及建築內部各部件如何有機的組成。
但是,軟件架構和建築架構有一個本質上的差異:那就是建築一旦完成就不會再變,而軟件卻需要根據業務的發展不斷的變化。對於建築來說,永恆是主題;而對於軟件來說,變化纔是主題。
如果沒有意識到 “軟件架構需要根據業務發展不斷變化” 這個本質,在做架構設計的時候很容易陷入一個誤區:試圖一步到位設計一個軟件架構,期望不管業務如何變化,架構都穩如磐石。如果是按照這樣的目標是設計,一開始上來就做出一套看似是終極的方案,投入龐大的資源做各種預測、分析。結果是投入巨大的資源、開發週期漫長,最終跌跌撞撞落地的系統,卻發現已經無法很好的滿足現有的業務。
所以技術架構設計需要一個過程:
首先,要滿足當前的業務需求進行技術架構設計
其次,架構要不斷地在實際應用過程中迭代,保留優秀的設計,修復有缺陷的設計,改正錯誤的設計,去掉無用的設計,使架構逐漸完善。
第三,當業務發生變化時,架構要擴展、重構、甚至重寫;代碼也許會重寫,但有價值的經驗、教訓、邏輯、設計卻可以在新架構中延續。
總結一下,演化原則就是演化優於一步到位。
戰術層設計原則
戰術層的設計原則分爲 3 部分:高併發原則、高可用原則、業務設計原則。這些原則是對技術架構設計過程中提供詳細的指導思路,幫助你做技術選型、技術拆分。
2.1 高併發原則
設計高併發的系統,需要考慮以下幾個方面的設計:無狀態、拆分、服務化、消息隊列、數據異構、緩存。
(1)無狀態
-
無狀態應用,便於水平擴展。
-
有狀態配置可通過配置中心實現無狀
(2) 拆分
-
系統維度:按照系統功能、業務拆分,比如購物車、結算、訂單等。
-
功能維度:對系統功能再做細粒度拆分。
-
讀寫維度:根據讀寫比例特徵拆分;讀多,可考慮多級緩存;寫多,可考慮分庫分表。
-
AOP 維度:根據訪問特徵,按照 AOP 進行拆分.
-
模塊維度:對整體代碼結構劃分 web、service、dao。
(3)服務化
-
服務化演進:進程內服務 - 單機遠程服務 - 集羣手動註冊服務 - 自動註冊和發現服務 - 服務的分組、隔離、路由 - 服務治理。
-
考慮服務分組、隔離、限流、黑白名單、超時、重試機制、路由、故障補償等。
(4)消息隊列
-
目的:服務解耦(一對多消費)、異步處理、流量削峯緩衝等。
-
大流量緩衝:犧牲強一致性,保障最終一致性。
-
數據校對:解決異步消息機制下消息丟失問題。
(5)數據異構
-
數據異構:通過消息隊列機制接受數據變更,原子化存儲。
-
數據閉環:屏蔽多重數據來源,將數據異構存儲,形成閉環。
(6)緩存
-
用戶層:DNS 緩存、瀏覽器 DNS 緩存、操作系統 DNS 緩存、本地 DNS 服務商緩存、DNS 服務器緩存、客戶端緩存、瀏覽器緩存、APP 客戶端緩存。
-
代理層:CDN 緩存(一般基於 ATS、Varnish、Nginx、Squid 等構建,邊緣節點 - 二級節點 - 中心節點 - 源站)
-
接入層:Nginx 的 Proxy_cache 代理緩存,或者 Nginx+Lua+Redis 做業務數據緩存。
-
應用層:頁面靜態化、業務數據緩存(Redis/Memcache/ 本地文件等)、消息隊列
-
數據層:NoSQL(Redis、Memcache、SSDB 等)
2.2 高可用原則
- 降級
-
降級開關集中化管理:將開關配置信息推送到各個應用。
-
可降級的多級讀服務:如服務調用降級爲只讀本地緩存。
-
開關前置化:如 Nginx+Lua 配置降級策略,引流流量;可基於此做灰度策略。
-
業務降級:高併發下,保證核心功能,次要功能可由同步改爲異步策略或屏蔽功能。
- 限流
-
目的:防止惡意請求攻擊或超過系統峯值
-
惡意請求流量只訪問到 Cache
-
穿透後端應用的流量 Nginx 的 limit 處理
-
惡意 Ip 使用 Nginx Deny 策略或者 iptables 拒絕
- 可回滾
- 發佈版本失敗時,可隨時快速回退到上一個穩定版本。
2.3 業務設計原則
-
防重設計
-
冪等設計
-
流程定義
-
狀態與狀態機
-
後臺系統操作可反饋
-
後臺系統審批化
-
文檔註釋
-
備份
技術架構圖
技術架構圖是將系統的技術方案、技術選型通過視圖的方式進行展現。技術架構圖分爲兩類:一類,功能需求技術架構圖(邏輯架構圖),是描繪如何通過技術組件來實現系統產品功能的圖。另一來,非功能需求技術架構圖(物理架構圖),是描繪如何通過物理部署的來實現系統運行的圖。
3.1 邏輯架構圖
功能需求技術架構圖以產品架構圖和應用架構圖爲基礎。實現每個功能點需要使用什麼技術、技術實現邏輯如何,就提現在技術架構圖上。功能需要技術架構圖繪製可以按照 “整體 - 局部 - 整體” 的思路實現。
1. 整體
首先可以按照應用架構圖的應用分佈得到應用分佈框架。如下:
圖 2
- 局部
在整體框架的基礎上,對每一個局部的子系統進行詳細的技術實現的表達。子系統的技術架構圖中需要展示每個子系統使用的技術組件,比如(緩存技術、消息中間件、流程引擎、流式計算框架等等)。同時,這些技術組件是如何實現業務功能,需要清晰的展示技術實現邏輯。
下圖是對風控系統中的實時引擎、離線引擎、準實時引擎三個子系統的進行的技術架構。在實時引擎中,主要使用 RuleEngine(規則引擎)作爲技術特點,這裏就重點列出 RuleEngine。準實時引擎使用 Blink 作爲流計算的技術框架,並概要的展示了計算邏輯。
圖 3
3. 整體
在完成每個子系統的技術實現後,最終進行一次整合,繪製一張總體的系統技術架構圖。各子系統之間通過服務接口、數據庫、緩存或消息中間等技術實現數據交互,以此將打通各個子系統,實現最終整個產品從數據、技術的串聯。
圖 4
3.2 物理架構圖
物理架構偏重於網絡設計、集羣設計、中間件設計、數據存儲設計等基礎軟硬件的設計架構。非功能需求的技術架構圖重點在於展示企業系統在物理上是如何部署。物理架構規定了組成系統的物理元素、物理元素之間的關係以及他們的部署策略。物理架構反映出軟件系統動態運行時的組織情況。從物理架構圖中,我們能夠全局的得知整個系統是如何從流量訪問、數據流轉、數據存儲到技術組件的運轉。
圖 5
總 結
我們從架構的本質開始,分別對業務架構、產品架構、數據架構、應用架構、技術架構的設計提供了一些思路和原則。這些思路和原則在進行架構設計和畫架構圖的過程中提供一些指導幫助。最後我們再來思考一個問題,好的軟件架構是規劃還是演化出來?
架構規劃對架構的影響是很重大的。首先,好的架構是設計出來的。好的架構,系統的性能和質量都將很高。架構設計的質量直接影響架構後續向好的方向演化的難易程度。架構設計如同城市規劃一樣,缺少規劃將難於演化。
圖 6
演化是一個過程,這個過程或長或短,所以演化需要考慮系統的生命週期。如果演化的過程非常漫長,超出了軟件的生命週期,即使架構越來越優化,對於產品或者項目的幫助也將有限,所以時間這個約束條件是非常苛刻的。
在現有規劃的基礎上進行演化,我們無法得到普適的架構,但可以得到確定領域的通用架構,可以在特定領域通過演化使架構逐步優化,幫助業務快速的發展。
作者簡介
胡斌,菜鳥網絡技術專家,目前負責菜鳥風控系統的建設。曾在淘寶技術部先後負責賣家平臺、商家運營等領域。在大規模分佈式應用、大數據、架構領域有多年的開發和管理經驗。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/jdCoY9zxFMDJemVttPDl4A