2016-12-13 71 views
5

我正在使用Java和Cassandra的事件採購從頭開始構建項目。 我的應用程序是基於微服務的,在某些使用情況下,信息將被異步處理。我想知道Message Queue(比如Rabbit,Active MQ Artemis,Kafka等)在這個環境中如何改進技術堆棧,以及如果我理解這些場景,我將不會使用它。事件源:何時(而不是)我應該使用Message Queue?

回答

3

請確保您明確了send(command)和publish(event)之間的區別。 Udi Dahan在他的文章busses and brokers上觸及了這個話題。

在大多數情況下,你是事件採購,你做而不是想要從發佈的事件重建狀態。如果你需要狀態,然後查詢歷史記錄的技術權威/記錄,並從歷史中重建狀態。

另一方面,事件驅動的活動關閉消息隊列應該沒問題。當一個事件(加上用戶的狀態)擁有你需要的一切時,那麼逃離總線就沒有問題。

在某些情況下,您可能會同時做這兩件事。例如,如果您正在更新緩存視圖,則可以訂閱各種BobChanged事件以瞭解緩存數據何時過時;要重建陳舊的視圖,您需要重新加載歷史記錄並將其轉換爲更新後的視圖。

1

在事件採購應用程序的世界中,消息隊列通常允許您實現生產者和消費者之間的發佈 - 訂閱模式風格的通信。此外,他們通常會幫助您提供交付保證:哪些郵件已發送給哪些訂閱者,哪些郵件未發送。

但它們不會無限期地存儲所有消息。你需要有一個活動商店來做任何事件採購。

的問題不是「排隊或者不排隊」,但它更像是:

  • 可這件事店內活動的巨大體積無限?
  • 它有發佈 - 訂閱功能嗎?
  • 是否提供至少一次交貨保證?

因此,您應該使用類似KafkaEventStore的東西來擁有所有的開箱即用功能。或者,您可以手動將事件存儲與消息隊列組合起來,但這會涉及更多。

6

我會從像Kafka這樣的事件流/存儲/處理中分離像RabbitMQ這樣的消息傳遞基礎結構。這些是爲了兩個(或更多)不同目的而做出的兩件事情。

關於事件採購,您必須有一個地方您必須存儲事件。此存儲必須是僅追加的,並支持基於身份快速讀取非結構化數據。這種持久性的一個例子是EventStore

事件採購與CQRS一起使用,這意味着您必須將您的更改(事件)投影到另一個可以查詢的商店。這是通過將事件投影到該商店來完成的,這是處理事件以更改域對象狀態的地方。理解使用消息基礎設施進行投影通常是一個壞主意是很重要的。這是由於消息傳遞和兩階段提交問題的性質。

如果查看事件如何持續存在,您可以看到它們作爲一個事務保存到商店。如果您需要發佈活動,這將是另一個交易。由於您正在處理兩種不同的基礎設施,因此事情可能會中斷。

這樣的消息傳遞問題是消息通常保證「至少傳遞一次」,並且通常不保證消息的順序。另外,當你的消息使用者失敗並且NACK消息時,它將被重新發送,但通常稍晚一點,再次破壞序列。

排序和複製問題,無論誰,不適用於像Kafka這樣的事件流服務器。另外,如果您使用追趕訂閱,則EventStore將保證只有一次事件傳遞順序。

根據我的經驗,消息用於發送命令並實現事件驅動架構以反應方式連接獨立服務。另一方面,事件存儲用於保存事件,只有到達那裏的事件才投影到查詢存儲併發布到消息總線。

+0

謝謝阿列克謝,在這裏的快速問題:「排序和複製問題,誰不適用於像卡夫卡這樣的事件流服務器」如何?如果你有併發訂閱者,如果這些併發訂閱者是相互依賴的,你將不可避免地開始有亂序問題,所以應該根據特定應用的業務規則在他們之間實現一些自定義同步。我的理解是否正確? – IlliakaillI

+0

我個人對Kafka沒有經驗,但是我觀看了關於DDDU 2016的Martin Kleppmann的談話https://dddeurope.com/2016/martin-kleppmann.html他解釋說,當他們設計Kafka時,他們的目標是嚴格按照事件順序進行。我也知道EventStore在使用catch/up訂閱時保證事件順序。當您在事件流上設置競爭消費者時,不可避免地會出現此保證,因此您無法在此確保訂購。異步處理也會破壞排序。 –

+0

我明白了。我在問,因爲在任何高可用性系統中,您必須讓競爭的用戶具有容錯能力,並且看起來像沒有機制可以自動處理這種系統的亂序情況。 – IlliakaillI

相關問題