命令觸發(fā)操作,操作觸發(fā)領域事件。領域事件保存在事件存儲中,也就是“一個將數(shù)據(jù)庫與消息代理相結(jié)合的系統(tǒng)。”最合適入門使用的事件存儲是Eventuate,是由Chris Richardson創(chuàng)建的項目,旨在幫助將CQRS和Event Sourcing應用到微服務。
領域事件存儲為按時間順序排列的一系列事件,附加在日志上。由于每個命令都生成一個事件,我們能夠根據(jù)收集的事件歷史記錄重新構(gòu)建當前系統(tǒng)的總體狀態(tài)。
事件處理器
我們要探討的下一個組件是事件處理器。這個CQRS組件采用Worker應用的形式,負責攝取領域事件。事件處理器是無狀態(tài)的,并偵聽來自事件存儲的消息,對傳入的事件消息采取操作。
事件處理器可通過很多有用的方式對新的領域事件作出響應。一個領域事件可以生成多個事件,這些事件可以發(fā)送到其他微服務。這就是為什么大多數(shù)微服務開發(fā)人員都被CQRS吸引,因為通過這種方法可以發(fā)布和訂閱來自限界環(huán)境之外的應用的領域事件。
這種方法為我們提供了一種機制,可確保領域數(shù)據(jù)的引用完整性。來自其他微服務的消息可用來處理領域事件,從而讓我們能夠維護分布式系統(tǒng)中與其他記錄的領域數(shù)據(jù)相關的惱人的外鍵關系。
查詢端
事件處理器首要負責應用可改變領域整合狀態(tài)的領域事件。每個領域事件都可用來更新數(shù)據(jù)庫記錄,形成描述整合的增量實體化視圖。反過來,查詢端將提供一個REST API,允許HTTP客戶端讀取從已處理事件生成的實體化視圖。
查詢端組件中的限制是領域數(shù)據(jù)是只讀的。此系統(tǒng)中的所有狀態(tài)更改都會從命令端流入,然后形成可在查詢端讀取的實體化視圖。
是分布式一體化還是微服務?
如今,大多數(shù)人想到單個微服務時,他們想到的是一個獨立的服務組件。在大多數(shù)情況下,微服務被構(gòu)建為應用,專注于處理好一件事情。最重要的是,這種服務可以獨立于其他服務進行升級和部署。
現(xiàn)在,如果說到傳統(tǒng)的CQRS實施,如果由于組件相互分離就稱之為微服務,似乎有些不妥。因此我們得問一句:可以將CQRS應用視為微服務嗎?或者換種說法,可以像某些開發(fā)人員那樣,開始稱之為分布式一體化嗎?對于這個問題,不同的人會有不同的答案。微服務主要是讓小型獨立團隊有能力持續(xù)交付功能,作為其他微服務組成的更大生態(tài)系統(tǒng)的一部分。
如果與大多數(shù)微服務部署相比,CQRS部署是十分復雜的。對于微服務團隊來說,能夠持續(xù)將功能交付至生產(chǎn)是目標。由于CQRS中分離的組件仍可以獨立部署,我們可以說每個部署單元仍可滿足獨立將功能交付至生產(chǎn)的最低要求。微服務的一個功能應該始終需要且最多一個可部署單元。當交付一項功能時需要同時協(xié)調(diào)部署多個單獨組件,就會產(chǎn)生所謂的分布式一體化。
微服務和無服務器
無服務器也稱為FaaS(功能即服務),可讓您在不需要設置或管理應用服務器或容器的情況下,將代碼部署為功能。無服務器是一種新型架構(gòu)風格,在構(gòu)建和運行云原生應用方面越來越受到關注。使用無服務器功能的一個顯著優(yōu)勢是,事件概念被優(yōu)先處理。
有很多人以為,微服務和無服務器不兼容,彼此的架構(gòu)風格完全不同。但是回想一下前面提到的CQRS你就會明白,這種想法是錯誤的。讓我們來看一個場景,你認為在此場景中微服務的邊界在哪里?
一種方法是認為微服務的邊界就是團隊的邊界。只要一個團隊可以獨立、連續(xù)地將特性部署為功能,那么微服務的邊界就只是負責為團隊擁有的特性提供支持的功能子集。
權衡
要采用微服務和無服務器相結(jié)合的方法,需要您仔細權衡多項內(nèi)容,讓我們來看看需要注意的事項。
速度
對于微服務來說,速度就是目標。我們可以通過關注以下兩個問題來衡量速度,平均時間越低,團隊交付功能的速度就越快。: