這是一個使用Spring Boot和Axon以及Docker構建的Event Sorucing源碼項目,技術特色:
1.使用Java 和Spring Boot實現微服務;
2.使用命令和查詢職責分離 (CQRS) 和 Event Sourcing (ES) 的框架Axon Framework v2, MongoDB 和 RabbitMQ;
3.使用Docker構建 交付和運行;
4.集中配置和使用Spring Cloud服務註冊;
5.使用Swagger 和 SpringFox 提供API文檔
項目源碼:GitHub
工做原理:
這個應用使用CQRS架構模式構建,在CQRS命令如ADD是和查詢VIEW(where id=1)分離的,在這個案例中領域部分代碼已經分離成兩個組件:一個是屬於命令這邊的微服務和屬性查詢這邊的微服務。
微服務是單個職責的功能,本身的數據存儲,每一個能彼此獨立擴展部署。
屬於命令這邊的微服務和屬性查詢這邊的微服務都是使用Spring Boot框架開發的,在命令微服務和查詢微服務之間通信是事件驅動,事件是經過RabbitMQ消息在微服務組件之間傳遞,消息提供了一種進程節點或微服務之間可擴展的事件載體,包括與傳統遺留系統或其餘系統的鬆耦合通信均可以經過消息進行。
請注意,服務之間不能彼此共享數據庫,這是很重要,由於微服務應該是高度自治自主的,這樣反過來有助於服務可以彼此獨立地擴展伸縮規模。
CQRS中命令是「改變狀態的動做」。命令的微服務包含全部領域邏輯和業務規則,命令被用於增長新的產品或改變它們的狀態,這些命令針對某個具體產品的執行會致使事件Event產生,這會經過Axon框架持久化到MongoDB中,而後經過RabbitMQ傳播給其餘節點進程或微服務。
在event-sourcing中,事件是狀態改變的原始記錄,它們用於系統來從新創建實體的當前狀態(經過從新播放過去的事件到當前就能夠構建當前的狀態),這聽上去會很慢,可是實際上,事件都很簡單,執行很是快,也能採起‘快照’策略進行優化。
請注意,在DDD中,實體是指一個聚合根實體。
上面是命令這邊的微服務,下面看看查詢這邊的微服務:
查詢微服務通常扮演一種事件監聽器和視圖角色,它監聽到命令那邊發出的事件,而後處理它們以符合查詢這邊的要求。
在這個案例中,查詢這邊只是簡單創建和維持了一個 ‘materialised view’或‘projection’ ,其中保留了產品的最新狀態,也就是產品id和描述以及是否被賣出等等信息,查詢這邊可以被複制屢次以方便擴展,消息能夠保留在RabbitMQ隊列中實現持久保存,這種臨時保存消息方式能夠防止查詢這邊微服務當機。
命令微服務和查詢微服務二者都有REST API,提供外界客戶端訪問。
下面看看如何經過Docker運行這個案例,須要 Ubuntu 16.04:
1.Docker ( v1.8.2)
2.Docker-compose ( v1.7.1)
在一個空目錄,執行下面命令下載docker-compose:html
$ wget https://raw.githubusercontent.com/benwilcock/microservice-sampler/master/docker-compose.yml
注意:不要更改文件名稱。
啓動微服務:只是簡單一個命令:git
$ docker-compose up
你會看到許多下載信息和日誌輸出在屏幕上,這是Docker image將被下載和運行。一共有六個docker,分別是: ‘mongodb’, ‘rabbitmq’, ‘config’, ‘discovery’, ‘product-cmd-side’, 和 ‘product-qry-side’.
使用下面命令進行測試增長一個新產品:github
$ curl -X POST -v --header "Content-Type: application/json" --header "Accept: */*" "http://localhost:9000/products/add/1?name=Everything%20Is%20Awesome"
查詢這個新產品:spring
$ curl http://localhost:9001/products/1
Microservices With Spring Boot, Axon CQRS/ES, and Docker mongodb