👉目錄
0?前言
1 宏觀
2?中觀
3 微觀
4 補充
俗話說,一圖勝千言。日常工作中,當我們要表達自己的設計思路的時候,會畫各式各樣的圖。但因為各自知識儲備的差異,思維的差異,不同類型的系統側重的架構設計點也不一樣(C端高并發系統、B端復雜業務系統、大數據離線系統、流式計算系統、機器學習系統、客戶端系統),導致在日常方案表達與溝通中,所畫出來的圖”五花八門“,沒有一個相對標準化、通用的”技術方案溝通語言“,這給溝通帶來歧義,同時也不利于個人的思維提升,不能形成一個體系化的思考方法。?
本文綜合了自己多年的架構設計實踐和業界眾多的軟件工程方法論,總結出一個相對通用的“技術方案溝通語言”。思維即語言,語言即思維,一切不能用“語言”表達的思維,只能說明沒思維。 更詳細介紹,還可以參見作者出版的書籍《軟件架構設計:大型網站技術架構與業務架構融合之道》
關注騰訊云開發者,一手技術干貨提前解鎖👇
00
前言
(1)不同的系統,復雜性往往體現在不同方面,畫圖的側重點不一樣,需要畫的是體現復雜性的那一面。
(2)本方法論考慮了方法論的投入與回報是否匹配問題,糅合了軟件4+1視圖、領域建模 (DDD)、 微服務拆分、UML、ER圖等幾個方法論。
系統的類型 | 側重點 |
1. C端大流量、高并發系統 | 系統架構、高并發、高可用等 |
2. B端復雜業務系統 | 領域建模、數據建模、微服務拆分。這里面又分為了2類:類型1: ?自身邏輯不復雜,但上下游的系統特別多、鏈條長; 類型2: ?上下游少(處在鏈條末端),但自身邏輯非常復雜; |
3. 基于大數據的各種業務系統 | 海量數據的處理問題(存儲、轉換、數據一致性保證) |
4. 數據分析、算法模型類系統 | 數據驅動的思路、模型、算法 |
下面的方法論,比較適合上面的前2類系統,第3類、第4類只在宏觀圖的畫法上有一點適合。
01
宏觀
???1.1?上下文圖
此圖目的:
讓別人明白你的系統的背景(業務背景、系統背景)。
思考方式:
把你的系統當做黑盒,描述2件事情:
你的系統為誰服務? (這個”誰“,可以是某個用戶,某個角色,也可以是某個系統) - - 你到哪去???
你的系統依賴誰? - - 你從哪來??
業界參考:
C4模型官網:https://c4model.com/
是否必選:
上下文很簡單的情況下,此圖可以和下面的”系統架構圖“合并成一個。
???1.2 系統架構圖
此圖目的:
(1)明確每個系統的定位與職責邊界,明白某個系統在整個體系中的“位置”在哪。
(2)明白跨團隊的各個系統,或者一個大系統的幾個子系統之間,是怎么串聯起來的。
思考方式:
(1)概要性的描述跨團隊的多個大系統之間的核心交互
(2)概要性的描述一個團隊的一個大系統內的多個子系統之間的核心交互。這2點糅合在一個圖上展示出來。
備注:這里說的系統/子系統,在物理上對應了一個集群(一個微服務的集群,或者一個獨立部署的系統)。
如果只是一個邏輯模塊,和其他代碼塊,部署在同一個進程里面的,不能算是一個”系統“,最好不要出現在此圖中。
是否必選:
簡單的系統,比如就1個單一的微服務,或者單體應用( UI+ 邏輯層 + ?DB),和外界其他系統沒有交互,此圖可以不畫。
???1.3?物理部署
目的:
有了物理部署,才能和上面的系統架構圖對應起來,讓人明白,上面的每個方塊,是一個集群,還是單機版的進程?
是單機版,是否存在高可用問題??
如果是集群,是不是多個系統,部署在同一批機器上?
畫法:
物理部署不一定需要圖,可以是一個表格,對上面的系統架構圖,進行補充。類似如下:
系統 /子系統 | 機房 | 機器數 | 對外提供的網絡協議:http/tcp/udp? | 備注 |
Java微服務1 | xx | 2臺 | http | |
子系統2 | xx | 1(單機版) | udp | |
... |
02
中觀
???2.1 是否要嚴格區分領域模型、數據模型(ER圖或者類圖)?
領域模型: DDD 、UML的思想,領域模型通常用UML來畫。
數據模型: ER圖,大家經常畫。
個人看法:嚴格區分這2者,實施起來往往非常難。如果2者不一致,不如不畫。
1、領域模型,大家不知道怎么畫?
2、領域模型到數據模型,如何映射、轉換,太隨意。雖然有教科書教大家轉換,但基本沒人學。
實體:表 = 1 :1的時候,領域模型映射到數據模型沒有歧義,但有很多例外情況:
(1)領域模型中的抽象/繼承,父類/子類,在ER中沒有體現
(2)領域實體之間的N:N關系,ER中需要中間表
(3)多個實體對應1張表
(4)視圖如何體現? 視圖指一種UI呈現,沒有數據存儲,多個數據表的數據按某種規則聚合成一個視圖
(5)領域模型中的策略、規則類的實體,最終映射到一段代碼邏輯,而不是表
所以結論是沒有嚴格區分領域模型,還是數據模型,主要以數據模型為主。
目的:
程序 = 數據結構 + 算法,軟件工程 = ?領域模型/數據模型 + 功能邏輯。
”數據結構“(這里指廣義的數據結構,不是大學教科書上的數據結構),是任何一個軟件的基石,其重要性怎么強調都不過分,系統的性能、復用性、擴展性、維護性、數據一致性等,往往都和“數據結構“密切相關。
對于嚴格遵循DDD的軟件開發,會區分領域模型和數據模型。但目前大部分實踐場景,并沒有對2者做嚴格區分。不管是領域模型,還是數據模型;不管是DB存儲、還是KV緩存/KV存儲、內存存儲,都會有一些共性的問題需要回答:
(1)你的系統有哪些關鍵的”實體“?
(2)這些實體之間的關系,是1:1, 1:N, N:1, N:N? 最終組成的這個網狀關系是什么樣的?
重點:
(1)ER圖和下面的3.2章節的表設計的區別是:3.2章節事無巨細的列每個字段的詳細解釋。這里ER圖是省略了大部分字段,只描述每個表的業務主鍵、外鍵、關鍵state,以及表與表之間的關聯關系。
(2)如果數據是存在KV存儲/KV緩存,同樣需要數據模型。因為kv里面的多個kv之間,可能有復雜的關聯關系。
如果部分數據在KV,部分數據在DB,更需要去很好的描述2者的關聯關系。這還涉及到2邊的數據一致性問題。
???2.2?時序圖
這個日常畫的最多,但也存在問題:
泳道中的每1列,是一個跨團隊的其他人的系統,還是自己系統內部的一個子系統,還是一個邏輯模塊,還是一個用戶?
盡可能在同一個層次上描述問題。
畫法:
直接參考UML。
???2.3?狀態圖
對于有復雜的狀態流轉的系統(對應DB中某個state字段),此圖一定要畫。
畫法:
直接參考UML。
???2.4 并發運行視圖
思考方式:
架構4+1理論中,有一個視圖就是”運行視圖“。主要描述單機的多線程/多進程之間如何通信、如何同步問題。
是否必須:
對于標準化的Java微服務,其微服務框架內部的多進程/多線程模型是固定的,上層開發人員只需要寫業務代碼。
對于這種情況,不需要去寫并發運行視圖,因為是標準化的,大家都一樣!
對于C++里面常見的自己從網絡框架層一直寫到業務層的系統,這個需要重點描述。沒有這個圖,沒辦法表達鎖、阻塞與喚醒、線程安全等各種并發問題。
在一個進程內部(RiskServer進程)內部的多線程模型,不要把多進程和多線程畫一個圖上,除非圖標上有明確區分是1個進程,還是線程。
???2.5?數據流程圖(離線大數據處理系統)
對于離線數據處理系統,數據鏈路可能很長,整個過程可能涉及到tdw/hdfs, ?hbase,絡子任務,java/c++處理,mysql,UI界面。。。
對于這類系統,數據流程圖非常關鍵。
03
微觀
這個大家已經很熟悉,不再展開。
接口文檔;
表設計(字段詳細解釋);
(1)自己的表,在哪個實例,哪個DB上面?
(2)每個表的字段解釋。
后臺任務;
(1)你的系統有多少個后臺任務,調度周期多少?
(2)單機版,還是分布式調度?實現方式:crontab, ?quartz, ?XXL-job,還是其他什么框架?
(3)后臺任務,跟服務,是部署在同一臺機器上面,還是不同?
04
補充
一個標準化的技術體系會極大的降低文檔編寫復雜度、降低團隊溝通難度:
當我說“接口”的時候,默認是某種標準化的RPC;
當我說“后臺任務”的時候,默認是某種標準化的分布式調度上面的一個任務;
當我說“消息”的時候,默認來自某種標準化的消息中間件;
當我說“DB”的時候,默認來自某種標準化的DB部署;
...
這一系列的”默認“,其產生的效率提升往往會超出預期。
-End-
原創作者|余春龍
感謝你讀到這里,不如關注一下?👇
📢📢來領開發者專屬福利!點擊下方圖片直達👇
你在架構設計中用過哪些好用的工具或方法?歡迎評論留言補充。我們將選取1則優質的評論,送出騰訊云定制文件袋套裝1個(見下圖)。6月18日中午12點開獎。