閱讀462 返回首頁    go 阿裏雲 go 技術社區[雲棲]


從事件和DDD入手來構建微服務

領域驅動設計(Domain-Driven Design,DDD)是一項很偉大的技術,它拉近了設計與程序實際所服務的領域,但是通常我們會關注結構,從而太早地做出決策,這並非DDD的本意。相反,在領域中,我們應該從事件開始,Russ Miles描述了在構建微服務時,采用“事件優先”的方式所具有的優勢。

Miles認為除了關注結構之外,我們還過多地關注了通用語言(ubiquitous language),尤其是在領域對象方麵更是如此。更糟糕的是,我們還會著手創建一些跨領域邊界重用的庫,這些庫中包含了領域對象,這實際上阻礙了不同邊界上下文(bounded context)的獨立演化。

在Miles的經驗中,對於企業級分層架構來說,這種方式已經成為了默認的架構風格,這麼做的原因在於它能夠讓事情變得更容易,而不是更簡潔或者有助於提升設計。這樣做會帶來一定的問題,比如實體變成了通用的,從隻位於某個上下文之中變成了跨所有上下文的規範,這是與DDD的理念背道而馳的。

與上麵提到的做法不同,Miles宣稱我們首先要從領域中發生了什麼入手,也就是事件。在領域中,它們能夠更好地捕獲通用語言,通常也是描述領域的最簡單的方式,尤其是在跟領域專家合作的時候更是如此。他發現無論是構建新的係統還是演化已有的係統,這種方式都非常適用。

Miles主張在使用事件時,第一步是事件風暴(Event Storming),這是由Alberto Brandolini所創建的一項建模工作坊技術。其基本理念就是通過領域中所發生的事情(也就是領域事件)來探索這個領域,並且使用便簽來描述領域中的事件,這些便簽會沿著時間軸貼到一個很大的建模麵板上。舉例來說,能夠引發事件的事情包括用戶行為、外部係統所發生的事情以及時間的流逝。事件也有助於找到領域的邊界,對術語的不同闡述可能就意味著存在邊界。

對Miles來說,另外一個導致複雜性的地方在於為錯誤的工作任務使用錯誤的模型。針對狀態的持久化,DDD提供了repository模式,通常的做法是在讀取和寫入方麵,使用相同的模型。這種方式帶來的一個好處就是一致性,但是如果需求稍微有所差別,那麼將讀取和寫入通過不同的模型進行分離將會取得明顯的收益。

命令查詢職責分離(Command Query Responsibility Segregation,CQRS)就是一種實現這種分離的技術:
命令作用於寫入模型上,並且要以一致的方式進行修改,最好是在一個聚集(aggregate)上,它會產生一個或多個事件。Miles指出所創建出來的事件並不是副產品,它們是命令的實際結果。 查詢使用一個或多個讀取模型,針對查詢會進行一些優化。寫入模型所生成的事件會被讀取模型接受到,讀取模型會進行更新,從而反映寫入模型的狀態。
事件溯源(Event sourcing)是對CQRS的自然擴展,在這裏聚集產生的所有事件都會進行持久化,可以用來重新創建聚集的狀態,而不是存儲狀態本身。按照Miles的說法,這種能力可以重建狀態,是一種降低狀態脆弱性的方法。

CQRS以及事件溯源會帶來其他的複雜性,比如最終一致性(eventual consistency);Greg Young是CQRS這個術語的創造者,他也對如今的事件溯源很感興趣,他認為這兩者都不是頂層的結構(top-level architecture)。按照Young的說法,它們隻能有選擇地應用於某些地方,他強調整個係統都基於事件溯源構建是一種反模式。

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

本文轉自d1net(轉載)

最後更新:2017-07-20 23:03:54

  上一篇:go  解讀利用大數據技術可以打敗癌症
  下一篇:go  拿到雲計算賬單嚇死人 這些省錢Tips你得知道