2017-07-02 119 views
13

微服務體系結構建議每個服務都應該處理它自己的數據。因此,依賴於其他服務(服務B)擁有的數據的任何服務(服務A)都應該訪問這些數據,而不是直接進行數據庫調用,而是通過第二服務(服務B)提供的API來訪問。微服務:如何處理外鍵關係

那麼微服務最佳實踐在檢查外鍵約束時提出了什麼建議。

示例:我正在開發產品的交付功能(microservice 1),並且某些產品僅可交付到產品表中提到的某些位置(僅適用於產品微服務(mircoservice 2))。

如何確保微服務1(即交付功能)不會將訂單交給非服務地點。我有這個問題,因爲交付功能不能直接訪問產品數據庫,所以當交貨單放入交貨數據庫時,在數據庫層面沒有適用的限制條件(無法檢查產品數據庫中是否存在外鍵匹配或表)。

回答

8

可以爲多個微服務使用共享數據庫。您可以在此鏈接中找到微服務的數據管理模式:http://microservices.io/patterns/data/database-per-service.html。順便說一下,這是一個非常有用的微服務架構博客。

就你而言,你更喜歡使用數據庫每服務模式。這使得微服務更加自主。在這種情況下,您應該在多個微服務中複製一些數據。您可以通過微服務之間的api調用共享數據,也可以與異步消息共享。這取決於您的基礎設施和數據更改的頻率。如果它不經常更改,則應該使用異步事件複製數據。

在您的示例中,Delivery service可以複製交付地點和產品信息。產品服務管理產品和地點。然後將所需數據複製到Delivery服務的數據庫中,並使用異步消息(例如,您可以使用rabbit mq或apache kafka)。交付服務不會更改產品和位置數據,但會在其工作時使用這些數據。如果傳遞服務使用的產品數據部分經常發生變化,則與異步消息傳遞的數據重複將會非常昂貴。在這種情況下,您應該在產品和送貨服務之間進行api調用。送貨服務要求產品服務人員檢查產品是否可交付到特定地點。送貨服務通過產品和地點的標識符(名稱,ID等)詢問產品服務。這些標識符可以從最終用戶處獲得,或者在微服務之間共享。因爲微服務的數據庫在這裏不同,所以我們不能在這些微服務的數據之間定義外鍵。

Api調用可能更容易實現,但網絡成本更高。當您進行api呼叫時,您的服務也不那麼自主。因爲在您的示例中,當產品服務停止時,傳遞服務無法完成其工作。如果使用異步消息傳遞複製數據,則交付所需的數據位於交付微服務的數據庫中。當產品服務不起作用時,您將能夠交貨。

+0

偉大的答案。我使用API​​調用,但它也需要對來自其他服務的數據進行排序和分頁。你知道這種情況的最佳方法嗎? – tranceholic

+0

您應該將與分頁和排序相關的參數添加到您的api中。然後,使用正確順序獲取正確頁面的責任將由api的消費者承擔。有一些技術用於定義像GraphQL這樣的api。據我所知,這些技術已經具有排序和分頁功能。如果您不使用這種技術,您可以簡單地從客戶端獲取參數並使用它們返回按頁面排序的數據。 –

4

分發代碼以實現減少耦合時,您希望避免資源共享,並且數據是您希望避免共享的資源。另一點是系統中只有一個組件擁有數據(用於狀態更改操作),其他組件可以讀取但不寫入,它們可以擁有數據的副本,或者可以共享可用於查看模型的視圖模型獲取對象的最新狀態。

引入參照完整性將重新引入耦合,相反,您希望爲主鍵使用Guid之類的東西,它們將由對象的創建者創建,其餘部分都是關於管理最終一致性。

看看烏迪大漢的talk in NDC Oslo for a more details

希望這有助於