2017-11-11 124 views
0

在傳統的微服務體系結構中,您可以在某些消息傳遞系統上發佈相關的域事件,從而允許系統的其他部分作出反應。Lagom的遠程持久化視圖

現在想象一下,你有三個微服務:客戶,訂單和建議推薦微服務需要客戶的信息訂單提供其功能,例如將要從某些機器學習算法分析的所有客戶和所有訂單的列表。 現在,你需要有客戶的狀態上Recommandation微服務「加盟」訂單:

  1. 你有Recommandation微服務聽取客戶和訂單公佈,並建立了自己的狀態域中的事件。這會導致邏輯重複,因爲您可能在客戶和訂單中已經具有相同的邏輯

  2. 在客戶和訂單的每個相關域消息中,您只需向他們詢問特定客戶或訂單的狀態。這很好,但是如果你有N個服務而不是僅僅需要建立一個物化視圖的服務,你將會對客戶和訂單造成很大的負擔

  3. 你讓Customers和Orders自己發佈「重量級」事件(不是域事件),它允許任何其他微服務在不處理域事件的情況下構建物化視圖。這可以讓你既a)不得複製邏輯B)不要不斷地問同樣的信息

有圖案N.3一些缺陷,我們無法弄清楚,如果沒有,你是如何實現它在Lagom?

回答

2

我會盡力解釋一些信息,希望能給你更多的關於這個問題的看法,以及如何在Lagom中以可靠的方式實現它。

我們有幾個概念,我們必須記住。其中最重要的是Event Sourcing本身。事件採購意味着系統中的任何國家都有其事件源。

我們要處理的第一個狀態是持久實體狀態。這個狀態很重要,因爲它與命令和事件處理程序一起定義了模型的一致性邊界。

但系統中還有其他國家。事實上,我們可以創建儘可能多的,因爲我們有Event Journal。閱讀模式也是一種狀態,也是由事件產生的。

有很多原因讓你不應該將PersistentEntity的狀態發佈到其他系統。第一個是避免耦合的問題。你不希望你的數據泄露給其他服務。這就是有一個反腐敗層(ACL)。

所以,從這裏我們可以這樣說:在發佈訂單和客戶推薦服務之前,我會將其轉換爲OrderView和CustomerView(ACL 101)。

現在的問題是什麼時候你會這樣做?如果您在處理命令後嘗試在卡夫卡發佈它,則您不能保證該州將被髮布。事件日誌和Kafka主題之間沒有XA事務。所以,有機會的話,該事件持續存在,但由於某些原因,國家沒有公佈卡夫卡。

如果你想要的數據走出以可靠的方式服務的,並不會產生業務之間的耦合,您有以下選擇:

使用代理API和發佈事件的話題。您不應按原樣發佈事件,而應將其轉換爲外部API(ACL)的格式。 使用讀出側處理器生成它的視圖中,再次你希望使用的外部API格式。如果您願意,可以將該ViewState發佈到某個主題,以便其他服務可以直接使用該主題。

這就是說,有什麼錯在發佈一個主題,是不是一個真正的事件中的東西,但一些派生的狀態。問題是你如何保證它被有效地發佈。這樣做,從PersistentEntity裏面是有風險的,因爲你必須在-一次的語義。做這件事最可靠的方法是一個只讀語法的讀取過程。

進一步說明在線......

傾聽來自客戶和訂單域事件,並在recommandation服務重建狀態 。這是一個可怕的想法,因爲你 將需要複製該處理在不同 界上下文

這不是一個可怕的想法事件的邏輯。這就是你如何讓你的服務彼此獨立。您需要實施以消耗事件的邏輯並不相同。正如你所說,這是一個不同的有限上下文,因爲它只獲得它所需要的。

泄漏從BC國家到另一個爲我上述(反腐敗層)的原因更成問題。

要實現脫鉤,你確實需要更多的代碼並沒有什麼不妥。在這一天結束時,構建微服務的原因是爲了避免耦合,並且能夠讓服務發展和擴展而不會相互干擾。有一個價格可以支付,價格是編寫更多的代碼。你需要評估線索。

可以消耗自己的事件,產生訂單查看CustomerView併發布到卡夫卡,但這是一樣直接消耗事件的推薦服務。

請注意,您還需要在一些地方保存訂單查看CustomerView的推薦服務。所以你最終要存儲三次。在原始服務(查看錶)上,在Kafka和推薦服務中。

這就是爲什麼在主題中發佈事件是在服務之間傳播數據的最佳選擇。

我們收到來自客戶或訂單域事件時,都會去 他們,並要求他們的狀態。這是可怕的,因爲如果你有更多的 比一個微服務需要自己的狀態,你最終會 生產客戶負荷和訂單

這的確是一個可怕的想法,因爲你會推薦服務依賴於另外兩項服務。如果訂單或客戶是向下,建議將普遍回落。這就是經紀人幫助解決的問題。

有客戶和訂單,不僅發佈事件也是國家和 具有需要建立的所有服務物化視圖聽 他們所需要的狀態如何申請與Lagom最後的模式?我們 發現沒有辦法聽狀態的變化,只是事件。一種解決方案 我們考慮暗示的出版與PubSub的狀態在持久性實體的onEvent 處理程序,但我不知道這是正確的 的地方,做到這一點。

在onEvent處理程序中使用pubSub是所有的最差解決方案。原因有以下幾點:

  1. PubSub的具有最多一次sematincs(見上述評論)

  2. 的事件處理程序調用多次。每當你重新水合物的實體,該事件被重播和事件處理程序將被用於這一點。這意味着你每次都會重新發布狀態。實際上,你就解決了最多一次,PubSub的問題,但不是這樣,你可能希望/慾望。

您可以使用afterPersist回調,但這並不可靠,因爲pubSub最多隻有一次。

PersistentEntity中的PubSub不應該用於您需要可靠的事情。這是一種盡力而爲的能力,就是這樣。