如今,每一個開發人員都很熟悉MVC標準體系結構設計模式。大多數的應用程序都是基於這種體系結構進行建立的。它容許咱們建立可擴展的大型企業應用程序,但近期咱們還聽到了另外的一些有關於CQRS/ES的相關信息。這些方法應該被放在MVC中一塊兒使用嗎?他們能夠解決什麼問題?如今,讓咱們一塊兒來看看CQRS/ES是什麼,以及他們都有哪些優勢和缺點。html
CQRS(Command Query Responsibility Segregation)是一種簡單的設計模式。它衍生與CQS,即命令和查詢分離,CQS是由Bertrand Meyer所設計。按照這一設計概念,系統中的方法應該分爲兩種:改變狀態的命令和返回值的查詢。Greg young將引入了這個設計概念,並將其應用於對象或者組件當中,這就是今天所要將的CQRS。它背後的主要思想是應用程序更改對象或組件狀態(Command)應該與獲取對象或者組件信息(Query)分開。數據庫
下面,將通一張圖來講明應用程序中有關CQRS部分的組成結構:設計模式
Commands(命令)—表示用戶的操做意圖。它們包含了與用戶將要對系統執行操做的全部必要信息。服務器
Query(查詢):表示用戶實際可用的應用程序狀態。獲取UI的數據應該經過這些對象完成。架構
下面咱們將介紹有關CQRS的諸多優勢,它們是:app
儘管使用CQRS模式具備上述諸多的優勢,可是在使用前還須要慎重考慮。對於只具備簡單域的簡單項目,其UI模型與域模型緊密聯繫的,使用CQRS反而會增長項目的複雜度和冗餘度,這無疑是過分的設計項目。此外,對於數據量較少或者性能要求較低的項目實施CQRS模式不會帶來顯著的性能提高。框架
有這樣一個案例,咱們想要檢索任何一個域對象的歷史狀態數據,並且在任什麼時候間均可以生成統計數據。咱們想要檢查上個月、上個季度或者過去任什麼時候間的狀態彙總。想要解決這個問題並不容易。咱們能夠在特定的時間範圍內將額外的數據保存在數據庫中,但這種方法也存在一些缺點。咱們不知道範圍應該是什麼樣子,以及將來統計數據須要哪些數據項。爲了不這些問題,咱們能夠天天爲全部聚合建立快照,但它們一樣會產生大量的冗餘數據。異步
Event Sourcing(ES)彷佛是目前解決這些問題的最佳方案。Event Sourcing容許咱們將Aggregate(聚合)狀態的每個更改事件保存在Event Store的事件存儲庫中。經過Command Handler將事件寫入到事件存儲庫中,並處理相關的邏輯。要建立Aggregate(聚合)對象的當前狀態,咱們須要運行建立預期域對象的全部事件並對其執行全部的更改。下面咱們將經過一張圖來講明這一架構設計方式:性能
下面咱們將列舉一些使用ES的優勢:學習
Aggregate(聚合)一詞在本文中屢次被說起,那它究竟是什麼意思?Aggregate(聚合)來自於領域驅動設計(DDD)的一個概念,它指的是始終保持一致狀態的實體或者相關實體組。咱們能夠簡單的理解爲接收和處理Command(包含Command Handler)的一個邊界,而後根據當前狀態生成事件。在一般狀況下,Aggregate root(聚合根)由一個域對象構成,但它能夠由多個對象組成。咱們還須要注意整個應用程序能夠包含多個Aggregate(聚合),而且全部事件都存儲在同一個存儲庫中。
CQRS/ES能夠做爲特定問題的解決方案。它能夠在標準N層架構設計的應用程序的某些層中進行引入,它能夠解決非標準問題,常規架構中咱們所拿到的是最終狀態,在不少狀況下,當然當前狀態很重要,但咱們還須要知道當前狀態是如何產生的。CQRS和ES兩種概念應該一塊兒使用嗎?事實代表,並無。咱們想要統計任什麼時候間範文內的域對象狀態,而寫庫只能存儲當前狀態。引入CQRS並沒能幫助咱們解決這一問題。在下一章節中,咱們將引入Axon框架,Axon框架時間了CQRS/ES,用於解決某些域對象的一些特定問題,尤爲是收集歷史統計數據。咱們將闡述如何使用Axon框架實現CQRS/ES並實現與Spring Boot應用程的整合。
做者:LukaszKucik ,譯:譚朝紅,原文: CQRS and Event Sourcing as an antidote for problems with retrieving application states,譯文: (譯)CQRS & EVENT SOURCING — 解決檢索應用程序狀態問題的一劑良方