天天看點

從事件和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(轉載)