近幾年來隨著微服務盛行, ES (Event Sourcing)事件溯源和CQRS (Command Query Responsibility Segregation)讀寫分離也成為了一個越來越流行的概念。2009年Allard Buijze在JVM平臺開源了Axon Framework,簡單說來Axon就是集成了DDD、ES和CQRS於一身,落地實現的一套框架方案,併成立了一家公司Axon IQ,專門與Axon產品合作。
一、Axon 框架簡介Axon Framework 透過支援開發者應用命令查詢職責分離(CQRS)架構模式,來幫助構建可伸縮、可擴充套件和可維護的應用程式。它透過提供最重要的構建塊來實現,如聚合、倉儲以及事件匯流排(事件的排程機制)。此外,Axon提供了對註解(annotation)的支援,它允許你構建聚合和事件監聽器,而不用將你的程式碼捆綁到Axon特有的邏輯。這使你能夠專注於業務邏輯,而不是資料傳輸(the plumbing),並幫助你使程式碼更容易隔離測試。
Axon不會試圖以任何方式隱藏CQRS架構或任何元件。因此,根據團隊規模,明智的選擇是,每個團隊中有一個或多個對CQRS有著透徹瞭解的開發人員。不管怎麼樣,Axon幫助保證把事件交付給正確的事件監聽器,並按正確的順序併發處理它們。這些多執行緒問題通常很難處理,導致難以跟蹤Bug、應用程式完全失去響應。當你的時間緊迫,你可能甚至不想去關心這些問題。Axon的程式碼是經過完全測試的,以防止這些型別錯誤的出現。
Axon Framework由多個模組(jar)組成,這些模組提供工具和元件來構建可伸縮的基礎設施。Axon核心模組為不同的元件提供了基本的API,併為單JVM的應用程式解決方案提供了簡單實現。其他模組提供專業的元件,來解決可伸縮性和高效能的問題。
Axon Framework的網站:www.axonframework.org
二、CQRS架構概述下圖顯示了一個示例,一個基於CQRS的事件驅動的架構圖示。 左側顯示的是UI元件, 透過兩種方式與應用程式的其餘部分進行互動:它嚮應用程式傳送命令 (顯示在頂端的部分),並從應用程式中查詢資訊 (顯示在底端的部分)。
Command(命令)通常用簡單的物件表示,這些物件包含命令處理器執行所需的所有資料。一個命令透過它的名字來表達它的意圖。在Java術語中,這意味著使用類名來確定需要做什 麼,命令的欄位提供了執行該操作所需的資訊。
Command Bus接受命令並路由它們到命令處理器(Command handler) 。每個命令處理器響應特定型別的命令,並根據命令的內容執行邏輯。
Command handler(命令處理器)從倉儲中恢復領域物件(聚合)並執行方法來改變它們的狀態。這些聚合通常包含真實的業務邏輯並負責維護自身的不變性。聚合的狀態變化導致了領域事件的產生,領域事件和聚合都從領域模型中來。
Repositories(倉儲)負責提供訪問聚合。通常情況下,這些倉儲的最佳化設計是僅透過其唯一識別符號來查詢聚合。一些倉儲將儲存聚合自身的狀態(例如,使用物件關係對映,ORM), 而另一些則儲存聚合的狀態的更改到Event Store中,倉儲還負責對其備份資料庫中的聚合進行更改。
Axon提供了直接持久化聚合(使用物件關係對映,ORM)和事件溯源(event sourcing)兩種方式。
Event bus(事件匯流排)分派事件到所有感興趣的事件監聽器(Event listener)中。可以同步或非同步完成。非同步事件排程允許命令執行返回和移交控制給使用者,這些事件在後臺被分派和處理,不必等待事件處理完成,這樣應用程式就會響應得更快。另一方面,同步事件處理更簡單,是一個合適的預設選項。 預設情況下,同步處理將在同一事務中處理事件監聽器和命令處理器。
Event listener(事件監聽器)接收並處理事件。一些處理器將更新用於查詢的資料來源,而其他處理器則將訊息傳送到外部系統。你可能會注意到了,命令處理器只對元件所做的更改感興趣,卻完全察覺不到它們的存在。這意味著它可以非侵入地擴充套件應用程式的新功能, 你需要做的就只是新增一個事件監聽器。事件讓應用程式中的所有元件鬆散耦合。
注意:並不是每一個應用程式都會從Axon中獲益。簡單的CRUD (Create, Read, Update, Delete) 應用程式、沒有橫向擴充套件預期的應用程式,可能無法從CQRS或Axon中受益。