本文由騰訊云架構(gòu)師技術(shù)同盟出品,「騰訊云架構(gòu)師技術(shù)同盟」是騰訊云為架構(gòu)領(lǐng)域知名專家與從業(yè)精英打造的專業(yè)技術(shù)社交圈,通過多樣的技術(shù)交流會(huì)議、社群專業(yè)探討、權(quán)威內(nèi)容輸出,打造業(yè)界領(lǐng)先的架構(gòu)師專業(yè)技術(shù)組織。同盟共創(chuàng),攜手同道,關(guān)注每一位中國(guó)架構(gòu)師成長(zhǎng)。
作者 | 余春龍
出品 | 騰訊云開發(fā)者
俗話說,一圖勝千言。日常工作中,當(dāng)我們要表達(dá)自己的設(shè)計(jì)思路的時(shí)候,會(huì)畫各式各樣的圖。但因?yàn)楦髯灾R(shí)儲(chǔ)備的差異,思維的差異,不同類型的系統(tǒng)側(cè)重的架構(gòu)設(shè)計(jì)點(diǎn)也不一樣(C端高并發(fā)系統(tǒng)、B端復(fù)雜業(yè)務(wù)系統(tǒng)、大數(shù)據(jù)離線系統(tǒng)、流式計(jì)算系統(tǒng)、機(jī)器學(xué)習(xí)系統(tǒng)、客戶端系統(tǒng)),導(dǎo)致在日常方案表達(dá)與溝通中,所畫出來的圖”五花八門“,沒有一個(gè)相對(duì)標(biāo)準(zhǔn)化、通用的”技術(shù)方案溝通語(yǔ)言“,這給溝通帶來歧義,同時(shí)也不利于個(gè)人的思維提升,不能形成一個(gè)體系化的思考方法。
本文綜合了自己多年的架構(gòu)設(shè)計(jì)實(shí)踐和業(yè)界眾多的軟件工程方法論,總結(jié)出一個(gè)相對(duì)通用的“技術(shù)方案溝通語(yǔ)言”。思維即語(yǔ)言,語(yǔ)言即思維,一切不能用“語(yǔ)言”表達(dá)的思維, 只能說明沒思維。
前言
(1)不同的系統(tǒng),復(fù)雜性往往體現(xiàn)在不同方面,畫圖的側(cè)重點(diǎn)不一樣,需要畫的是體現(xiàn)復(fù)雜性的那一面。
(2)本方法論考慮了方法論的投入與回報(bào)是否匹配問題,糅合了軟件4+1視圖、領(lǐng)域建模 (DDD)、 微服務(wù)拆分、UML、ER圖等幾個(gè)方法論。
下面的方法論,比較適合上面的前2類系統(tǒng),第3類、第4類只在宏觀圖的畫法上有一點(diǎn)適合。
宏觀
1.1上下文圖
此圖目的:
讓別人明白你的系統(tǒng)的背景(業(yè)務(wù)背景、系統(tǒng)背景)。
思考方式:
把你的系統(tǒng)當(dāng)做黑盒,描述2件事情:
1、你的系統(tǒng)為誰(shuí)服務(wù)? (這個(gè)”誰(shuí)“,可以是某個(gè)用戶,某個(gè)角色,也可以是某個(gè)系統(tǒng)) - - 你到哪去???
2、你的系統(tǒng)依賴誰(shuí)? - - 你從哪來??
業(yè)界參考:
C4模型官網(wǎng):https://c4model.com/
是否必選:
上下文很簡(jiǎn)單的情況下,此圖可以和下面的”系統(tǒng)架構(gòu)圖“合并成一個(gè)。
1.2 系統(tǒng)架構(gòu)圖
此圖目的:
(1)明確每個(gè)系統(tǒng)的定位與職責(zé)邊界,明白某個(gè)系統(tǒng)在整個(gè)體系中的“位置”在哪。
(2)明白跨團(tuán)隊(duì)的各個(gè)系統(tǒng),或者一個(gè)大系統(tǒng)的幾個(gè)子系統(tǒng)之間,是怎么串聯(lián)起來的。
思考方式:
(1)概要性的描述跨團(tuán)隊(duì)的多個(gè)大系統(tǒng)之間的核心交互
(2)概要性的描述一個(gè)團(tuán)隊(duì)的一個(gè)大系統(tǒng)內(nèi)的多個(gè)子系統(tǒng)之間的核心交互。這2點(diǎn)糅合在一個(gè)圖上展示出來。
備注:這里說的系統(tǒng)/子系統(tǒng),在物理上對(duì)應(yīng)了一個(gè)集群(一個(gè)微服務(wù)的集群,或者一個(gè)獨(dú)立部署的系統(tǒng))。
如果只是一個(gè)邏輯模塊,和其他代碼塊,部署在同一個(gè)進(jìn)程里面的,不能算是一個(gè)”系統(tǒng)“,最好不要出現(xiàn)在此圖中。
是否必選:
簡(jiǎn)單的系統(tǒng),比如就1個(gè)單一的微服務(wù),或者單體應(yīng)用( UI+ 邏輯層 + DB),和外界其他系統(tǒng)沒有交互,此圖可以不畫。
1.3物理部署
目的:
有了物理部署,才能和上面的系統(tǒng)架構(gòu)圖對(duì)應(yīng)起來,讓人明白,上面的每個(gè)方塊,是一個(gè)集群,還是單機(jī)版的進(jìn)程?
是單機(jī)版,是否存在高可用問題?
如果是集群,是不是多個(gè)系統(tǒng),部署在同一批機(jī)器上?
畫法:
物理部署不一定需要圖,可以是一個(gè)表格,對(duì)上面的系統(tǒng)架構(gòu)圖,進(jìn)行補(bǔ)充。類似如下:
中觀
2.1 是否要嚴(yán)格區(qū)分領(lǐng)域模型、數(shù)據(jù)模型(ER圖或者類圖)?
領(lǐng)域模型: DDD 、UML的思想,領(lǐng)域模型通常用UML來畫。
數(shù)據(jù)模型: ER圖,大家經(jīng)常畫。
個(gè)人看法:嚴(yán)格區(qū)分這2者,實(shí)施起來往往非常難。如果2者不一致,不如不畫。
1、領(lǐng)域模型,大家不知道怎么畫
2、領(lǐng)域模型到數(shù)據(jù)模型,如何映射、轉(zhuǎn)換,太隨意。雖然有教科書教大家轉(zhuǎn)換,但基本沒人學(xué)。
實(shí)體:表 = 1 :1的時(shí)候,領(lǐng)域模型映射到數(shù)據(jù)模型沒有歧義,但有很多例外情況:
(1)領(lǐng)域模型中的抽象/繼承,父類/子類,在ER中沒有體現(xiàn)
(2)領(lǐng)域?qū)嶓w之間的N:N關(guān)系,ER中需要中間表
(3)多個(gè)實(shí)體對(duì)應(yīng)1張表
(4)視圖如何體現(xiàn)? 視圖指一種UI呈現(xiàn),沒有數(shù)據(jù)存儲(chǔ),多個(gè)數(shù)據(jù)表的數(shù)據(jù)按某種規(guī)則聚合成一個(gè)視圖
(5)領(lǐng)域模型中的策略、規(guī)則類的實(shí)體,最終映射到一段代碼邏輯,而不是表
所以結(jié)論是沒有嚴(yán)格區(qū)分領(lǐng)域模型,還是數(shù)據(jù)模型,主要以數(shù)據(jù)模型為主。
目的:
程序 = 數(shù)據(jù)結(jié)構(gòu) + 算法,軟件工程 = 領(lǐng)域模型/數(shù)據(jù)模型 + 功能邏輯。
”數(shù)據(jù)結(jié)構(gòu)“(這里指廣義的數(shù)據(jù)結(jié)構(gòu),不是大學(xué)教科書上的數(shù)據(jù)結(jié)構(gòu)),是任何一個(gè)軟件的基石,其重要性怎么強(qiáng)調(diào)都不過分,系統(tǒng)的性能、復(fù)用性、擴(kuò)展性、維護(hù)性、數(shù)據(jù)一致性等,往往都和“數(shù)據(jù)結(jié)構(gòu)“密切相關(guān)。
對(duì)于嚴(yán)格遵循DDD的軟件開發(fā),會(huì)區(qū)分領(lǐng)域模型和數(shù)據(jù)模型。但目前大部分實(shí)踐場(chǎng)景,并沒有對(duì)2者做嚴(yán)格區(qū)分。不管是領(lǐng)域模型,還是數(shù)據(jù)模型;不管是DB存儲(chǔ)、還是KV緩存/KV存儲(chǔ)、內(nèi)存存儲(chǔ),都會(huì)有一些共性的問題需要回答:
(1)你的系統(tǒng)有哪些關(guān)鍵的”實(shí)體“?
(2)這些實(shí)體之間的關(guān)系,是1:1, 1:N, N:1, N:N? 最終組成的這個(gè)網(wǎng)狀關(guān)系是什么樣的?
重點(diǎn):
(1)ER圖和下面的3.2章節(jié)的表設(shè)計(jì)的區(qū)別是:3.2章節(jié)事無巨細(xì)的列每個(gè)字段的詳細(xì)解釋。這里ER圖是省略了大部分字段,只描述每個(gè)表的業(yè)務(wù)主鍵、外鍵、關(guān)鍵state,以及表與表之間的關(guān)聯(lián)關(guān)系。
(2)如果數(shù)據(jù)是存在KV存儲(chǔ)/KV緩存,同樣需要數(shù)據(jù)模型。因?yàn)閗v里面的多個(gè)kv之間,可能有復(fù)雜的關(guān)聯(lián)關(guān)系。
如果部分?jǐn)?shù)據(jù)在KV,部分?jǐn)?shù)據(jù)在DB,更需要去很好的描述2者的關(guān)聯(lián)關(guān)系。這還涉及到2邊的數(shù)據(jù)一致性問題。
2.2時(shí)序圖
這個(gè)日常畫的最多,但也存在問題:
泳道中的每1列,是一個(gè)跨團(tuán)隊(duì)的其他人的系統(tǒng),還是自己系統(tǒng)內(nèi)部的一個(gè)子系統(tǒng),還是一個(gè)邏輯模塊,還是一個(gè)用戶?
盡可能在同一個(gè)層次上描述問題。
畫法:
直接參考UML。
2.3狀態(tài)圖
對(duì)于有復(fù)雜的狀態(tài)流轉(zhuǎn)的系統(tǒng)(對(duì)應(yīng)DB中某個(gè)state字段),此圖一定要畫。
畫法:
直接參考UML。
2.4 并發(fā)運(yùn)行視圖
思考方式:
架構(gòu)4+1理論中,有一個(gè)視圖就是”運(yùn)行視圖“。主要描述單機(jī)的多線程/多進(jìn)程之間如何通信、如何同步問題。
是否必須:
對(duì)于標(biāo)準(zhǔn)化的Java微服務(wù),其微服務(wù)框架內(nèi)部的多進(jìn)程/多線程模型是固定的,上層開發(fā)人員只需要寫業(yè)務(wù)代碼。
對(duì)于這種情況,不需要去寫并發(fā)運(yùn)行視圖,因?yàn)槭菢?biāo)準(zhǔn)化的,大家都一樣!
對(duì)于C++里面常見的自己從網(wǎng)絡(luò)框架層一直寫到業(yè)務(wù)層的系統(tǒng),這個(gè)需要重點(diǎn)描述。沒有這個(gè)圖,沒辦法表達(dá)鎖、阻塞與喚醒、線程安全等各種并發(fā)問題。
在一個(gè)進(jìn)程內(nèi)部(RiskServer進(jìn)程)內(nèi)部的多線程模型,不要把多進(jìn)程和多線程畫一個(gè)圖上,除非圖標(biāo)上有明確區(qū)分是1個(gè)進(jìn)程,還是線程。
2.5數(shù)據(jù)流程圖(離線大數(shù)據(jù)處理系統(tǒng))
對(duì)于離線數(shù)據(jù)處理系統(tǒng),數(shù)據(jù)鏈路可能很長(zhǎng),整個(gè)過程可能涉及到tdw/hdfs, hbase,絡(luò)子任務(wù),java/c++處理,mysql,UI界面。。。
對(duì)于這類系統(tǒng),數(shù)據(jù)流程圖非常關(guān)鍵。
微觀
這個(gè)大家已經(jīng)很熟悉,不再展開。
接口文檔;
表設(shè)計(jì)(字段詳細(xì)解釋);
(1)自己的表,在哪個(gè)實(shí)例,哪個(gè)DB上面?
(2)每個(gè)表的字段解釋。
后臺(tái)任務(wù);
(1)你的系統(tǒng)有多少個(gè)后臺(tái)任務(wù),調(diào)度周期多少?
(2)單機(jī)版,還是分布式調(diào)度?實(shí)現(xiàn)方式:crontab, quartz, XXL-job,還是其他什么框架?
(3)后臺(tái)任務(wù),跟服務(wù),是部署在同一臺(tái)機(jī)器上面,還是不同?
補(bǔ)充
一個(gè)標(biāo)準(zhǔn)化的技術(shù)體系會(huì)極大的降低文檔編寫復(fù)雜度、降低團(tuán)隊(duì)溝通難度:
當(dāng)我說“接口”的時(shí)候,默認(rèn)是某種標(biāo)準(zhǔn)化的RPC;
當(dāng)我說“后臺(tái)任務(wù)”的時(shí)候,默認(rèn)是某種標(biāo)準(zhǔn)化的分布式調(diào)度上面的一個(gè)任務(wù);
當(dāng)我說“消息”的時(shí)候,默認(rèn)來自某種標(biāo)準(zhǔn)化的消息中間件;
當(dāng)我說“DB”的時(shí)候,默認(rèn)來自某種標(biāo)準(zhǔn)化的DB部署;
這一系列的”默認(rèn)“,其產(chǎn)生的效率提升往往會(huì)超出預(yù)期。
感謝你讀到這里,不如關(guān)注一下?
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.