2012-07-05 49 views
3

我目前正在調查使用NServiceBus解決以下問題。我只是想確保我不會在這個兔子洞裏走。多線程CQRS與NServiceBus

我有一個基於CQRS架構的解決方案。本質上,我有一系列命令通過NServiceBus傳遞給端點,我執行一些處理來改變聚合根的狀態,然後發出一系列事件來通知系統其餘部分的變化。

我的問題是,這一切都很好的一個線程,我不需要擔心鎖定任何給定的聚合根,而我改變狀態。

我們已經到了一個線程不會削減它的地步,我需要開始研究使用多個工作線程/進程來處理消息。

根據我可以同時處理多個聚合根的事實,有一個自然的任務分解,但是我不能同時處理同一個聚合根的多個消息,因爲這會導致高由於收到消息的速度而導致的爭用。

我想避免這種情況,我需要鎖定一個特定的聚合根ID,而是將一個聚合根分配給隊列/線程/進程,這將確保來自同一聚合根的所有消息都被同步處理。

我正在使用NServiceBus的Pub/Sub模型發佈事件。就我所看到的問題而言,這些事件需要從同一端點發布,即使該消息的處理可能委託給另一個端點。即當我實際上在「MyDomainQueue-Worker1」上處理消息時,我需要欺騙系統認爲消息是從「MyDomainQueue」發佈的。

我的計劃是創建一個自定義分配器,它允許主端點將消息處理委託給工作端點。分發者將以循環方式爲任何給定的聚合根分配一個隊列。主要端點將向這些工作人員發送命令,處理將發生,並且工作人員將回復一系列事件。主要終端會將這些事件重新發布到公交車上。

我在尋找一些關於這種方法的反饋。感覺就像我正在努力工作一樣,我只想檢查是否有其他人處理了類似的問題。也許NServiceBus是這個工作的錯誤工具,或者我的方法可能是錯誤的。任何和所有的反饋是受歡迎的。

謝謝,

PS - 我也有在其周圍將需要上述的溶液中的構型的量的擔憂。

+1

你看看內置的分銷商嗎?有關3/4下面的內容,請參閱下面的頁面,它描述了一個擴展的Pub/Sub模型。 http://nservicebus.com/DistributorV3.aspx –

回答

1

關於發佈來自不同端點的事件,我認爲您對於從一個服務發佈的事件的概念有點太過興趣。僅在邏輯意義上這是真實的 - 一個事件應該完全由一個邏輯服務擁有,然而邏輯服務可以由許多端點組成。

事件並非真正從隊列中發佈。當你想到發佈事件的隊列時,你真正在談論的是你發送該事件訂閱請求的輸入隊列。

因此,只要對該事件的訂閱請求都發送到同一個地方,就可以讓多個端點都發布相同的事件。

例如,在批量與優先級​​情況下,您有兩個端點處理相同的命令(然後發佈相同的事件),除了一個批量使用長SLA,而另一個有一個更短的SLA - 也許它是一個大客戶,或者命令來自實際的用戶等待響應。 QueueA和PriorityQueueA都處理相同的命令併發布相同的事件,但QueueA處理訂閱,因此兩個進程都從QueueA「發佈」。

這就是說,你有沒有試圖讓多個線程訪問聚合根?即使有一些爭議,你可能會發現只要少量重試就可能沒有你想象的那麼有爭議。在NServiceBus的生產環境中,我有一些相當有爭議的進程,雖然我偶爾會看到爭用的證據是日誌中的一個異常,但有5次重試,我從來沒有任何進展到錯誤隊列。

- 最近,增加了二級重試功能,這進一步降低了錯誤隊列中消息結束的機會。

如果存在很多爭用,另一種策略可能是維護目前正在操作的聚合根目錄的內存列表,然後如果出現應該「鎖定」的消息,則只需撥打Bus.HandleCurrentMessageLater()即可堅持消息返回到隊列末尾。

+0

感謝您的建議。我將陷入對poc的進展提供反饋。 Bus.HandleCurrentMessageLater()讓我思考。我應該能夠與此合作。 –

+0

只是關於具有多個端點的邏輯服務的問題。這是否意味着訂閱者需要在兩個(所有)端點上訂閱相同的事件? –

+0

不,訂閱者訂閱(或者說,發送訂閱請求到)一個邏輯授權源。這就是訂閱存儲的地方。然後,多個*物理*端點可以將同一事件發佈爲一個統一*邏輯*發佈者。 –