2011-04-13 100 views
6

我試圖在我的新項目中使用CQRS和EventSorcing。我遵循Greg Young在幾年前提出的方式(Mark Nijhof實施 - http://cre8ivethought.com/blog/2009/11/12/cqrs--la-greg-young/)。而且我對這個解決方案的可伸縮性有一些問題。CQRS + EventSourcing可擴展性

Mark Nijhof的文章this提到了一些觀點。但現在的問題是Denormalizer部分,它負責更新報告數據庫。這部分我想做異步,所以在發佈事件到總線後,我想立即返回控制權。我們建議Denormalizer可以作爲一個獨立的Web服務(WCF)來實現,它將處理傳入的事件並通過批量命令以時間方式更新報表數據庫。看起來它可能是一個瓶頸,所以我們也希望在這一點上增加一些可擴展性 - 一個集羣解決方案。但是在集羣的情況下,我們無法控制報告數據庫更新的順序(或者我們應該執行一些奇怪的事情,並且我猜測它會檢查報告數據庫中的對象版本)。另一個問題是解決方案的可持續性:在失敗的情況下,我們將在denormalizer中丟失更新,只要我們不會將它們堅持到任何地方)。所以現在我尋找解決這個問題的方法(Denormalizer可擴展性),歡迎任何想法!

回答

4

首先,您肯定會希望將denormalizer託管在單獨的進程中。從那裏你可以讓域名發佈到你的消息傳遞基礎設施中發生在域中的事件。幫助加速非規範化的一個簡單策略是通過消息/事件類型將事情分開。換句話說,您可以爲每個消息類型創建一個單獨的隊列,然後讓denormalizer訂閱(使用消息總線)相應的事件。這樣做的好處是你沒有消息堆疊在一起 - 所有東西都開始平行運行。唯一可能存在爭用的地方就是聽多種類型的表。即便如此,你現在已經在許多終端中分配了負載。

只要您使用某種消息傳遞基礎結構,當嘗試進行非規範化時,您不會丟失事件消息。相反,經過一定數量的失敗重試後,該消息將被視爲「中毒」並移至錯誤隊列。只需監視錯誤隊列中的問題。一旦消息在錯誤隊列中,您可以檢查日誌以瞭解其原因,解決問題,然後將其移回。

另一個考慮因素是Mark Nijhof的例子有些老舊。在DDD/CQRS Google Group中有許多CQRS框架以及建議。

+0

是否有可能爲每個視圖模型而不是每個事件分別設置一個隊列? – 2011-04-13 14:37:24

+0

絕對如此。總線基礎設施(如NServiceBus)將訂閱適當的事件並告訴發佈者它需要適用於特定視圖模型的消息的副本。 – 2011-04-13 16:10:30

+0

感謝您的回答喬納森。那麼,我也想到了一些針對denormalizer的事件分離策略,例如在單獨的線程中有幾個隊列。我想這裏唯一的規則是保持每個特定聚合根的事件序列。但是這裏的問題是我不知道如何在這種情況下使用集羣,或者甚至可以使用它,因爲集羣可以打破事件的順序。 – Voice 2011-04-13 19:02:59