DDD戰(zhàn)略篇:架構(gòu)設(shè)計(jì)的響應(yīng)力
當(dāng)敏捷宣言的17位簽署者在2001年喊出“響應(yīng)變化勝于遵循計(jì)劃”這樣的口號(hào)時(shí),鮮有組織會(huì)真正把這句話當(dāng)回事兒,甚至很多經(jīng)驗(yàn)豐富的管理者會(huì)認(rèn)為好的計(jì)劃是成功的一半,遵循計(jì)劃就是另外一半。然而在時(shí)下的第四次工業(yè)革命浪潮中,可能很多管理者已經(jīng)不會(huì)簡(jiǎn)單滿足于“響應(yīng)”,而是選擇主動(dòng)發(fā)起變化了。不確定性管理成了這個(gè)時(shí)代的主旋律,企業(yè)的響應(yīng)力成了成敗的關(guān)鍵。
隨著這種趨勢(shì)的深入,架構(gòu)設(shè)計(jì)這個(gè)技術(shù)管理領(lǐng)域也被推到了風(fēng)暴邊緣。“穩(wěn)定”這個(gè)過(guò)去我們用來(lái)形容好系統(tǒng)的詞語(yǔ)似乎已經(jīng)失去原有的含義,很多人開(kāi)始用“健壯”這個(gè)詞語(yǔ)來(lái)形容好的系統(tǒng)。比如Netflix公司采用的Chaos Monkey機(jī)制隨機(jī)主動(dòng)關(guān)停線上服務(wù)而不會(huì)造成整個(gè)服務(wù)生態(tài)宕機(jī)的作法更多的是在測(cè)試系統(tǒng)的健壯性,保證不會(huì)因?yàn)槟硞€(gè)局部的問(wèn)題而造成全身癱瘓。
然而架構(gòu)的健壯性卻比較難于定義和測(cè)試,以至于很多時(shí)候咱們?cè)诩軜?gòu)設(shè)計(jì)上還是在追求穩(wěn)定性。在一個(gè)典型的企業(yè)IT組織里,當(dāng)你詢問(wèn)一位資深工程師架構(gòu)設(shè)計(jì)時(shí),往往會(huì)得到一張搭積木一樣的“架構(gòu)圖”。
圖的底層是各種數(shù)據(jù)存儲(chǔ)(從經(jīng)典的Oracle到大數(shù)據(jù)標(biāo)配的Hadoop),圖的中間是類似Kafaka這樣的消息管道和傳統(tǒng)的ESB(消息總線),上層則是各種業(yè)務(wù)應(yīng)用(包括各種Web應(yīng)用和移動(dòng)的APP)。
仿佛這是一個(gè)流行的“穩(wěn)定”架構(gòu)設(shè)計(jì)。
(示意:典型的IT系統(tǒng)架構(gòu)圖)
當(dāng)詢問(wèn)這樣的架構(gòu)是否合理時(shí),不少人會(huì)告訴你問(wèn)題可大了:這不是云時(shí)代的服務(wù)化架構(gòu)。原因是這個(gè)架構(gòu)的大部分組件,如數(shù)據(jù)存儲(chǔ),都已經(jīng)可以完全“托管”給云平臺(tái)了。于是乎,很多企業(yè)架構(gòu)師又開(kāi)始尋找像過(guò)去ESB一樣能夠?qū)痈鞣N云平臺(tái)的PaaS了,然后抱怨現(xiàn)在的PaaS沒(méi)有當(dāng)年的ESB“穩(wěn)定”。
兩個(gè)核心問(wèn)題卻很少被提及:
- 當(dāng)年基于ESB集成的SOA服務(wù)化架構(gòu)解耦出的組件不但沒(méi)有提升效率,反而增加了系統(tǒng)后續(xù)修改的復(fù)雜度。
- 看似“以不變應(yīng)萬(wàn)變”的架構(gòu)并不能支撐多樣化的業(yè)務(wù)需求,最后各個(gè)業(yè)務(wù)部門仍然有一套自己的IT系統(tǒng),即便是畫出來(lái)的架構(gòu)圖驚人的相似(多少次有人驚呼“這就是我們之前那個(gè)工作流系統(tǒng)~”)。
就這兩個(gè)核心痛點(diǎn),讓我們一起來(lái)談?wù)劶軜?gòu)設(shè)計(jì)面臨的挑戰(zhàn)和應(yīng)對(duì)方式。
什么是架構(gòu)設(shè)計(jì)
由于軟件設(shè)計(jì)是一個(gè)復(fù)雜度很高的活動(dòng),“通過(guò)組件化完成關(guān)注點(diǎn)分離從而降低局部復(fù)雜度”很早就成為了咱們這個(gè)行業(yè)的共識(shí)。前面提到的數(shù)據(jù)存儲(chǔ)、消息管道等“模塊”在某種意義上都是組件化的產(chǎn)物。這樣的好處是在不同系統(tǒng)里遇到同樣的功能需求時(shí)可以復(fù)用。在云服務(wù)崛起的今天,這樣的組件以“服務(wù)”的形式更容易為我們所采用。
當(dāng)然技術(shù)出身的架構(gòu)師們?cè)诩軜?gòu)設(shè)計(jì)的時(shí)候或多或少都有一種“搭積木”的感覺(jué)。大家都非常關(guān)注Kafaka有哪些功能,K8S是不是比Mesos功能更全,以及Akka是不是穩(wěn)定。就像走進(jìn)一個(gè)家裝公司,在選擇了“套餐”之后有工程人員給你介紹地磚和木地板用哪個(gè)品牌更好。
回到咱們的第二個(gè)核心痛點(diǎn),如果只是這樣的搭積木,為什么咱們總是在面對(duì)新變化、新需求的時(shí)候發(fā)現(xiàn)需要新的組裝方式或新的組件呢?這樣的架構(gòu)設(shè)計(jì)對(duì)比直接按照需求實(shí)現(xiàn)(不考慮架構(gòu))有什么優(yōu)勢(shì)呢?
這里我們應(yīng)該回到架構(gòu)設(shè)計(jì)的本質(zhì),即為什么我們要在代碼實(shí)現(xiàn)前做設(shè)計(jì)。顯然如果去掉設(shè)計(jì)這個(gè)過(guò)程,大家會(huì)說(shuō)問(wèn)題這么復(fù)雜,如何下手啊?所以設(shè)計(jì)首先是要解決問(wèn)題的復(fù)雜度。于是有人做了一個(gè)架構(gòu),交給了一個(gè)團(tuán)隊(duì)去實(shí)現(xiàn),很快發(fā)現(xiàn)實(shí)現(xiàn)的架構(gòu)和設(shè)計(jì)完全是兩張皮。當(dāng)然原因很明確——缺少了交流和溝通,所以設(shè)計(jì)其次是要建立團(tuán)隊(duì)協(xié)作溝通的共識(shí)。
假設(shè)我們產(chǎn)生了一個(gè)團(tuán)隊(duì)都達(dá)成共識(shí)的架構(gòu)設(shè)計(jì),大家都兢兢業(yè)業(yè)把設(shè)計(jì)變成了現(xiàn)實(shí)。一個(gè)長(zhǎng)期困擾軟件行業(yè)的問(wèn)題出現(xiàn)了,需求總是在變化,無(wú)論預(yù)先設(shè)計(jì)如何“精確”,總是發(fā)現(xiàn)下一個(gè)坑就在不遠(yuǎn)處。相信很多技術(shù)人員都有這樣的經(jīng)歷,結(jié)果往往是情況越來(lái)越糟糕,也就是我們常說(shuō)的架構(gòu)腐化了,最后大家不得不接受重寫。這些經(jīng)歷讓我們逐步明確了軟件架構(gòu)設(shè)計(jì)的實(shí)質(zhì)是讓系統(tǒng)能夠更快地響應(yīng)外界業(yè)務(wù)的變化,并且使得系統(tǒng)能夠持續(xù)演進(jìn)。在遇到變化時(shí)不需要從頭開(kāi)始,保證實(shí)現(xiàn)成本得到有效控制。
面向業(yè)務(wù)變化而架構(gòu)
基于上面的架構(gòu)設(shè)計(jì)定義,關(guān)鍵因素就是業(yè)務(wù)變化。顯然這個(gè)時(shí)代的業(yè)務(wù)變化是很快的,甚至很多業(yè)務(wù)主動(dòng)在變,不變則亡是很多行業(yè)目前的共識(shí)。變化速度給架構(gòu)設(shè)計(jì)帶來(lái)了很大挑戰(zhàn),一個(gè)移動(dòng)APP可能需要在一周內(nèi)上線,然而為了支撐這個(gè)移動(dòng)APP的后臺(tái)服務(wù),平臺(tái)發(fā)布窗口是每?jī)蓚€(gè)月一次。這樣的不匹配在IT領(lǐng)域里是隨處可見(jiàn)的現(xiàn)實(shí),我們習(xí)慣性地認(rèn)為后臺(tái)天然就很重因此很慢,只可能在犧牲質(zhì)量的情況下滿足這樣的速度。
然而事實(shí)上這樣的健壯架構(gòu)確實(shí)是存在的,看看身邊現(xiàn)在無(wú)處不在的互聯(lián)網(wǎng),又有哪一個(gè)企業(yè)的架構(gòu)比之復(fù)雜呢。互聯(lián)網(wǎng)系統(tǒng)的組件是一個(gè)個(gè)網(wǎng)站,每個(gè)網(wǎng)站完成著自己的業(yè)務(wù)功能更新,從新聞發(fā)布到在線聊天。而各個(gè)站點(diǎn)又是緊密互聯(lián)的,聊天網(wǎng)站可能把新聞網(wǎng)站拿到的信息實(shí)時(shí)推送給在線的用戶。每個(gè)網(wǎng)站都是獨(dú)立的小單元,面向互聯(lián)網(wǎng)用戶提供著一定的業(yè)務(wù)服務(wù)。好的網(wǎng)站也根據(jù)用戶的反饋在不停升級(jí)和變化,但這樣的變化并不影響用戶使用其它的網(wǎng)站。
從互聯(lián)網(wǎng)架構(gòu)我們可以學(xué)到什么呢?從架構(gòu)設(shè)計(jì)角度我認(rèn)為以下三點(diǎn)是關(guān)鍵。
- 讓我們的組件劃分盡量靠近變化的原點(diǎn),對(duì)于互聯(lián)網(wǎng)來(lái)說(shuō)就是用戶和業(yè)務(wù),這樣的劃分能夠讓我們將變化“隔離”在一定的范圍(組件)內(nèi),從而幫助我們有效減少改變點(diǎn)。
- 組件之間能夠互相調(diào)用,但彼此之間不應(yīng)該有強(qiáng)依賴,即各自完成的業(yè)務(wù)是相對(duì)獨(dú)立的,不會(huì)因?yàn)橐环降艟€而牽連另外一方,比如新聞網(wǎng)站掛掉了,聊天網(wǎng)站應(yīng)該繼續(xù)正常提供服務(wù),可能提示用戶暫時(shí)無(wú)法提供新聞信息而已。
- 組件在業(yè)務(wù)上是鼓勵(lì)復(fù)用的,正是這樣的復(fù)用才成就了今天的互聯(lián)網(wǎng),我們不會(huì)每個(gè)網(wǎng)站都去實(shí)現(xiàn)一個(gè)強(qiáng)大的搜索引擎。而被“復(fù)用”最多的網(wǎng)站顯然會(huì)受到追捧,成為明星業(yè)務(wù)。當(dāng)然架構(gòu)上這樣的網(wǎng)站必然是健壯的。
上面的三點(diǎn)毫無(wú)疑問(wèn)都指向了業(yè)務(wù),從業(yè)務(wù)出發(fā)、面向業(yè)務(wù)變化是我們現(xiàn)代架構(gòu)設(shè)計(jì)成功的關(guān)鍵。
架構(gòu)設(shè)計(jì)的核心實(shí)質(zhì)是保證面對(duì)業(yè)務(wù)變化時(shí)我們能夠有足夠快的響應(yīng)能力。
這種響應(yīng)力體現(xiàn)在新需求(變化)的實(shí)現(xiàn)速度上,也體現(xiàn)在我們組件的復(fù)用上,在實(shí)現(xiàn)過(guò)程中現(xiàn)有架構(gòu)和代碼變化點(diǎn)的數(shù)量也是技術(shù)人員能夠切身體會(huì)到的。面對(duì)日新月異的數(shù)字化時(shí)代,組織的整體關(guān)注點(diǎn)都應(yīng)該集中到變化的原點(diǎn),即業(yè)務(wù)上,而架構(gòu)應(yīng)該服務(wù)于這種組織模式,讓這樣的模式落地變得自然。
對(duì)比之前的傳統(tǒng)SOA架構(gòu),這個(gè)思路的變化是本質(zhì)性的。類似工業(yè)總線(ESB)這樣的組件化其實(shí)是面向技術(shù)的,希望通過(guò)技術(shù)平臺(tái)的靈活性來(lái)解決業(yè)務(wù)變化的多樣性。雖然短時(shí)間能夠收到一定的成效,長(zhǎng)期看必然把自身做成瓶頸,因?yàn)樗袠I(yè)務(wù)的變化最后都堆積到了這個(gè)技術(shù)組件來(lái)解決。這也回答了為什么實(shí)施了傳統(tǒng)SOA架構(gòu)的企業(yè)最后都發(fā)現(xiàn)響應(yīng)速度其實(shí)并沒(méi)有提升起來(lái)。
面向業(yè)務(wù)變化而架構(gòu)就要求首先理解業(yè)務(wù)的核心問(wèn)題,即有針對(duì)性地進(jìn)行關(guān)注點(diǎn)分離來(lái)找到相對(duì)內(nèi)聚的業(yè)務(wù)活動(dòng)形成子問(wèn)題域。子問(wèn)題域內(nèi)部是相對(duì)穩(wěn)定的,即未來(lái)的變化頻率不會(huì)很高,而子問(wèn)題邊界是很容易變化的,比如在一個(gè)物流系統(tǒng)中:計(jì)算貨物從A地到B地的路徑是相對(duì)固定的,計(jì)算包裹的體積及歸類也是相對(duì)固定的,但根據(jù)包裹的體積優(yōu)化路徑卻經(jīng)常會(huì)根據(jù)業(yè)務(wù)條件而變化。
(子問(wèn)題域的劃分)
面對(duì)業(yè)務(wù)的變化也要求我們的架構(gòu)必須是演進(jìn)的,因?yàn)闃I(yè)務(wù)的變化點(diǎn)也會(huì)隨著時(shí)間推移發(fā)生著變化。這意味著在一款較長(zhǎng)生命周期的軟件產(chǎn)品中,不會(huì)出現(xiàn)類似ESB這樣的重型組件,相反的我們追求的是一些面向業(yè)務(wù)服務(wù)的輕量級(jí)組件,它們的持續(xù)演進(jìn)也會(huì)造成老組件的合并,新組件的重新拆分。當(dāng)然這也成了現(xiàn)代微服務(wù)架構(gòu)成功的基礎(chǔ)條件之一。
打造架構(gòu)響應(yīng)力的方法
如果認(rèn)同了上述現(xiàn)代架構(gòu)的真正意義,大家一定會(huì)問(wèn)怎么才能打造這樣的高響應(yīng)力架構(gòu)呢?
領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)方法DDD(Domain Driven Design)為我們提供了很好的切入點(diǎn)。這個(gè)2003年就總結(jié)出來(lái)的方法終于在10多年后重新走入了架構(gòu)師的視野,而這一次大家已經(jīng)意識(shí)到了這種方法在這個(gè)快速變化時(shí)代的重要性。DDD通過(guò)以下兩個(gè)模式去有效解決了文章開(kāi)始提到的兩大痛點(diǎn):
- 讓團(tuán)隊(duì)中各個(gè)角色(從業(yè)務(wù)到開(kāi)發(fā)測(cè)試)都能夠采用統(tǒng)一的架構(gòu)語(yǔ)言,從而避免組件劃分過(guò)程中的邊界錯(cuò)位。
- 讓業(yè)務(wù)架構(gòu)和系統(tǒng)架構(gòu)形成綁定關(guān)系,從而建立針對(duì)業(yè)務(wù)變化的高響應(yīng)力架構(gòu)。
這兩點(diǎn)是DDD的核心,也是為什么時(shí)下全球架構(gòu)圈在進(jìn)一步向DDD這個(gè)方向靠攏的原因。DDD明確了業(yè)務(wù)和系統(tǒng)架構(gòu)上的綁定關(guān)系,并提供了一套元語(yǔ)言來(lái)幫助各個(gè)角色有效交流架構(gòu)設(shè)計(jì)。
(DDD的基本方法)
在戰(zhàn)略層面,DDD非常強(qiáng)調(diào)針對(duì)業(yè)務(wù)問(wèn)題的分析和分解,通過(guò)識(shí)別核心問(wèn)題域來(lái)降低分析的復(fù)雜度。在戰(zhàn)術(shù)層面,DDD強(qiáng)調(diào)通過(guò)識(shí)別問(wèn)題域里的不同業(yè)務(wù)上下文來(lái)進(jìn)行面向業(yè)務(wù)需求的組件化。最后在實(shí)現(xiàn)層面利用成熟的技術(shù)模式屏蔽掉技術(shù)細(xì)節(jié)的復(fù)雜度。
【本文是51CTO專欄作者“ThoughtWorks”的原創(chuàng)稿件,微信公眾號(hào):思特沃克,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】































