DDD之聚合與事件溯源[A +ES]

在開發(fā)微服務(wù)的過程中,分布式數(shù)據(jù)管理是必須解決的問題。不同服務(wù)數(shù)據(jù)庫選擇的多樣性,事務(wù)問題及跨服務(wù)的數(shù)據(jù)查詢都是我們要面對的挑戰(zhàn)。


對于大多數(shù)應用而言,要實現(xiàn)微服務(wù)和管理分布數(shù)據(jù),都需要采用事件驅(qū)動架構(gòu)。在事件驅(qū)動架構(gòu)中,某個服務(wù)在發(fā)生重要事情的時候,比如,創(chuàng)建一個訂單會發(fā)布一個事件,而其他服務(wù)訂閱這些事件。作為對事件的回應,接收事件的服務(wù)通常會更新自身的狀態(tài),或許會發(fā)布更多事件,讓其他服務(wù)進行更新。


我們分析一下上述用例,我的的業(yè)務(wù)代碼必需完成在MySQL數(shù)據(jù)庫中加入訂單相關(guān)數(shù)據(jù)并將事件發(fā)布到Kafka中。如何避免不一致性發(fā)生,保證這兩個操作在同一個事務(wù)中呢?

傳統(tǒng)方法中,我們可以使用包含數(shù)據(jù)庫和消息代理的分布式事務(wù),但我們都知道分布式事務(wù)帶來的諸多問題與限制,。然而,事件溯源(Event Sourcing)也是一個不錯的辦法。它已經(jīng)存在了幾十年,直到Greg Young用于DDD中后,逐步流行了起來。

這里我們借助Martin Fowler對事件溯源給出的一些解釋:

事件溯源的核心理念是說,在對系統(tǒng)的狀態(tài)做出變更時,把每次變更記錄為一個事件,在未來的任何時刻,都可以通過重新處理這些事件來重建系統(tǒng)的狀態(tài)。事件存儲是主要的事件來源,可以從事件存儲中重建系統(tǒng)的狀態(tài)。對于程序員來說,版本控制系統(tǒng)是一個最好的例子。提交日志就是事件存儲,而代碼工作副本就是系統(tǒng)狀態(tài)。在某個指定的工作副本上重播提交日志就可以創(chuàng)建另一個工作副本,也就是重建了某個時刻的系統(tǒng)狀態(tài)。

拿訂單為例,在整個訂單的生命周期中所發(fā)生的重要的事情,都會記錄在事件存儲中。

再看看事件事件溯源是如何工作的:

這里的訂單是訂單服務(wù)中的訂單聚合,可能有的讀者會問,這樣的架構(gòu)怎樣解決訂單更新與保存的一致性呢?其實訂單沒有對應的MySQL數(shù)據(jù)庫,只存在于內(nèi)存中,需要持久化的只有訂單業(yè)務(wù)過程中的領(lǐng)域事件,保存在了事件存儲中,單一的存儲類型,這樣就不存在一致性問題了。

關(guān)于不同服務(wù)的joins問題,事件溯源推薦使用CQRS架構(gòu),將查詢與事件處理分離,在DDD中我們會定義成領(lǐng)域報告。詳細內(nèi)容后續(xù)文章會有處理。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容