從事件和DDD入手來(lái)構(gòu)建微服務(wù)

責(zé)任編輯:editor004

作者:Jan Stenberg

2017-01-09 10:35:56

摘自:INFOQ

領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(Domain-Driven Design,DDD)是一項(xiàng)很偉大的技術(shù),它拉近了設(shè)計(jì)與程序?qū)嶋H所服務(wù)的領(lǐng)域,但是通常我們會(huì)關(guān)注結(jié)構(gòu)

領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(Domain-Driven Design,DDD)是一項(xiàng)很偉大的技術(shù),它拉近了設(shè)計(jì)與程序?qū)嶋H所服務(wù)的領(lǐng)域,但是通常我們會(huì)關(guān)注結(jié)構(gòu),從而太早地做出決策,這并非DDD的本意。相反,在領(lǐng)域中,我們應(yīng)該從事件開(kāi)始,Russ Miles描述了在構(gòu)建微服務(wù)時(shí),采用“事件優(yōu)先”的方式所具有的優(yōu)勢(shì)。

Miles認(rèn)為除了關(guān)注結(jié)構(gòu)之外,我們還過(guò)多地關(guān)注了通用語(yǔ)言(ubiquitous language),尤其是在領(lǐng)域?qū)ο蠓矫娓侨绱恕8愀獾氖?,我們還會(huì)著手創(chuàng)建一些跨領(lǐng)域邊界重用的庫(kù),這些庫(kù)中包含了領(lǐng)域?qū)ο?,這實(shí)際上阻礙了不同邊界上下文(bounded context)的獨(dú)立演化。

在Miles的經(jīng)驗(yàn)中,對(duì)于企業(yè)級(jí)分層架構(gòu)來(lái)說(shuō),這種方式已經(jīng)成為了默認(rèn)的架構(gòu)風(fēng)格,這么做的原因在于它能夠讓事情變得更容易,而不是更簡(jiǎn)潔或者有助于提升設(shè)計(jì)。這樣做會(huì)帶來(lái)一定的問(wèn)題,比如實(shí)體變成了通用的,從只位于某個(gè)上下文之中變成了跨所有上下文的規(guī)范,這是與DDD的理念背道而馳的。

與上面提到的做法不同,Miles宣稱(chēng)我們首先要從領(lǐng)域中發(fā)生了什么入手,也就是事件。在領(lǐng)域中,它們能夠更好地捕獲通用語(yǔ)言,通常也是描述領(lǐng)域的最簡(jiǎn)單的方式,尤其是在跟領(lǐng)域?qū)<液献鞯臅r(shí)候更是如此。他發(fā)現(xiàn)無(wú)論是構(gòu)建新的系統(tǒng)還是演化已有的系統(tǒng),這種方式都非常適用。

Miles主張?jiān)谑褂檬录r(shí),第一步是事件風(fēng)暴(Event Storming),這是由Alberto Brandolini所創(chuàng)建的一項(xiàng)建模工作坊技術(shù)。其基本理念就是通過(guò)領(lǐng)域中所發(fā)生的事情(也就是領(lǐng)域事件)來(lái)探索這個(gè)領(lǐng)域,并且使用便簽來(lái)描述領(lǐng)域中的事件,這些便簽會(huì)沿著時(shí)間軸貼到一個(gè)很大的建模面板上。舉例來(lái)說(shuō),能夠引發(fā)事件的事情包括用戶(hù)行為、外部系統(tǒng)所發(fā)生的事情以及時(shí)間的流逝。事件也有助于找到領(lǐng)域的邊界,對(duì)術(shù)語(yǔ)的不同闡述可能就意味著存在邊界。

對(duì)Miles來(lái)說(shuō),另外一個(gè)導(dǎo)致復(fù)雜性的地方在于為錯(cuò)誤的工作任務(wù)使用錯(cuò)誤的模型。針對(duì)狀態(tài)的持久化,DDD提供了repository模式,通常的做法是在讀取和寫(xiě)入方面,使用相同的模型。這種方式帶來(lái)的一個(gè)好處就是一致性,但是如果需求稍微有所差別,那么將讀取和寫(xiě)入通過(guò)不同的模型進(jìn)行分離將會(huì)取得明顯的收益。

命令查詢(xún)職責(zé)分離(Command Query Responsibility Segregation,CQRS)就是一種實(shí)現(xiàn)這種分離的技術(shù):

命令作用于寫(xiě)入模型上,并且要以一致的方式進(jìn)行修改,最好是在一個(gè)聚集(aggregate)上,它會(huì)產(chǎn)生一個(gè)或多個(gè)事件。Miles指出所創(chuàng)建出來(lái)的事件并不是副產(chǎn)品,它們是命令的實(shí)際結(jié)果。 查詢(xún)使用一個(gè)或多個(gè)讀取模型,針對(duì)查詢(xún)會(huì)進(jìn)行一些優(yōu)化。寫(xiě)入模型所生成的事件會(huì)被讀取模型接受到,讀取模型會(huì)進(jìn)行更新,從而反映寫(xiě)入模型的狀態(tài)。

事件溯源(Event sourcing)是對(duì)CQRS的自然擴(kuò)展,在這里聚集產(chǎn)生的所有事件都會(huì)進(jìn)行持久化,可以用來(lái)重新創(chuàng)建聚集的狀態(tài),而不是存儲(chǔ)狀態(tài)本身。按照Miles的說(shuō)法,這種能力可以重建狀態(tài),是一種降低狀態(tài)脆弱性的方法。

CQRS以及事件溯源會(huì)帶來(lái)其他的復(fù)雜性,比如最終一致性(eventual consistency);Greg Young是CQRS這個(gè)術(shù)語(yǔ)的創(chuàng)造者,他也對(duì)如今的事件溯源很感興趣,他認(rèn)為這兩者都不是頂層的結(jié)構(gòu)(top-level architecture)。按照Young的說(shuō)法,它們只能有選擇地應(yīng)用于某些地方,他強(qiáng)調(diào)整個(gè)系統(tǒng)都基于事件溯源構(gòu)建是一種反模式。

查看英文原文:Start with Events and DDD When Building Microservice

鏈接已復(fù)制,快去分享吧

企業(yè)網(wǎng)版權(quán)所有?2010-2024 京ICP備09108050號(hào)-6京公網(wǎng)安備 11010502049343號(hào)