背 景 前端
2004年,Eric Evans發表了Domain Driven Design(領域驅動設計,DDD)這一著做,並在書中對領域驅動做出了開創性的理論闡述,至今領域驅動設計已問世十幾年。web
近幾年來隨着微服務盛行, ES (Event Sourcing)事件溯源和CQRS (Command Query Responsibility Segregation)讀寫分離也成爲了一個愈來愈流行的概念,使用ES和CQRS好處在此不作贅述,可是也存在頗多弊端,好比事件數量巨大、回溯狀態須要提早預熱、缺乏成熟的框架支撐等。在這種狀況下,2009年Allard Buijze在JVM平臺開源了Axon Framework用來解決此問題,簡單說來Axon就是集成了DDD、ES和CQRS於一身,落地實現的一套框架方案,併成立了一家公司Axon IQ,專門與Axon產品合做。數據庫
愛奇藝號技術團隊,在實施微服務化過程當中,應用領取驅動思想,採用Axon框架落地了多個服務,下面是實施過程當中的經驗總結。後端
技術選型安全
愛奇藝號合同中臺面向用戶提供簽約功能,從發起簽約到運營審覈、供應商、採購單、掃描件、歸檔等流程漫長,狀態頗多,業務較爲複雜,同第三方系統交互較多,對於有問題數據須要進行定位和回溯。項目初期爲了更好的知足這些需求,咱們調研了一下比較成熟的框架,包括Cola、Axon、Activiti、Spring StateMachine等,圖1-1是框架的一些對比:微信
圖1-1架構
從對比中能夠看出,Axon支持事件回溯,排查歷史問題較爲方便,而且官方文檔完善,一直處於更新維護中。StateMachine較爲輕量,流程變動對於歷史數據兼容性良好。綜合考慮採用Axon+StateMachine相結合,實現簡版工做流引擎。併發
Axon框架介紹框架
Axon框架的程序遵循基於領域驅動設計(DDD)、命令查詢責任隔離 (CQRS)、事件驅動架構(Event Driven Architecture,EDA)的體系結構模式,這些原則的結合,使基於Axon的程序更加健壯、適應性更強。圖1- 2是基於Axon框架程序的典型體系結構:分佈式
圖1-2
基於Axon框架程序的典型體系結構圖特性以下:
-
領域驅動模型:可使業務實體不會「貧血」,更加飽滿,實現高內聚、低耦合; -
命令查詢責任隔離:命令模型和查詢模型的分離,使得每一個模型更容易理解,更易開發維護,自然適合高併發場景; 事件驅動架構:支持事件溯源,方便對歷史事件重放,記錄數據變化完整過程,便於BI分析、線上問題排查、還原系統狀態到任意時間點等。
Axon系統調用鏈如圖1-3所示:
圖1-3
Spring StateMachine介紹
Spring StateMachine是使用 Spring框架下的狀態機概念建立的一種應用程序開發框架。它使得狀態機結構層次化,簡化了配置狀態機的過程。擁有有現狀態機的特性功能:現態、條件、動做、次態,支持觸發器、狀態轉移器、保護機制、狀態轉移動做和狀態事件監聽器,可基於Zookeeper實現分佈式狀態機,可配置多層次、結構複雜的狀態機。圖1-4是簡單配置效果圖:
圖1-4
愛奇藝號合同中臺服務實踐
【項目介紹】
用戶入駐愛奇藝號後發表做品會得到分紅收益,帳號知足必定條件後能夠申請提現,提現以前須要跟公司簽約電子合同。爲了保證合同安全有效,線上簽約流程比較漫長,包括用戶填寫信息、運營審覈、採購單申請審覈、合同審覈、合同附件蓋章郵寄、做品關聯等等,累計20+狀態,業務邏輯較爲複雜,需求迭代變動頻繁,對數據一致性要求較高。
項目1.0版本採用的是Activiti工做流做爲引擎設計實現的,基於Activiti特性,能夠嚴格控制每一步狀態的流轉,歷史操做事件都會記錄到系統數據庫中,對於線上問題排查有必定的優點。可是學習成本較大,須要開發人員瞭解框架系統的二十多張表功能、使用BMPN進行流程定義設計等。圖1-5是最第一版本的流程設計圖:
圖1-5
圖1-6
用戶接口層:主要是MQ消息、UI和API接口,接收用戶請求、運營審批命令、第三方系統交互通知等;
應用層:接口參數校驗、組裝業務參數,轉換成Axon Command進行命令分發;
領域層:接收到領域事件,轉換成狀態機Event,驅動狀態機進行狀態更迭,觸發對應業務邏輯處理;
-
基礎服務層:提供底層存儲服務,第三方服務等。
系統調用流程以下圖1-7:
圖1-7
Axon+StateMachine結合,實現簡版工做流引擎功能,相比於Activiti更加輕量級。以合同對象多爲領域對象,系統操做命令使用狀態機進行控制流轉。全部對系統的修改操做均以Axon的Command進行,Axon會記錄全部對領域對象操做過的事件,能夠還原合同生命週期內每一步的狀態,對於問題排查,統計分析有着很大的幫助;snapshot機制對事件進行預熱,解決事件過多加載慢的問題;sage對系統失敗操做進行補償事件,保證系統間數據狀態的一致性;StateMachine特性,能夠修改狀態之間流轉走向及流轉條件,新增狀態對於歷史數據或者進行中的數據沒有影響,對系統的迭代開發有很大的效率提高,自然適合互聯網性質工做流。
價 值
一、 開發方面的優點
轉換思惟:Java語言開發一直提倡面向對象開發,可是不少業務開發人員的思惟仍是面向過程開發的思惟,按照MVC分層進行業務代碼的堆疊。Axon思惟更傾向於面向對象,以領域對象爲核心,因爲領域對象有明確的領域邊界,因此容易促進開發人員思惟模式的轉變。
提高開發效率:項目基於命令模型開發,可讓熟悉業務的開發人員專一於領域層開發,接口和應用層開發則能夠由對業務比較陌生的開發人員負責,兩者經過命令發送消息機制進行通訊。這種職責分離的優點在於不須要全部的開發人員都對業務很是熟悉,減小了熟悉具體業務的時間,且每一個開發人員都職責明確,可顯著提高開發效率。
二、 運行維護時的優點
便於問題排查:事件溯源機制使得領域對象的每次操做變動狀態都有記錄,對於排查線上問題有很大的幫助,能夠按照前後順序還原對象的每一步狀態。snapshot機制有很好的解決了ES事件預熱的問題。對於BI的分析也有着更好的支撐。
支持系統高吞吐量:CQRS的支持,自然適合高併發場景,若是系統有高併發的需求,使用Axon框架能夠獲得更好的支持。
便於維護和拓展:Axon框架的代碼層次清晰,易維護,使用的事件機制讓系統更具可擴展性。
難 點
-
分佈式事務一致性問題,saga雖然能保證分佈式事務的最終一致性,可是實施起來困難很大,須要開發各類補償機制來實現。並且沒有考慮到服務的宕機、冪等、重試支持等問題 批量事務處理能力較弱,對於一些批量功能,目前只能轉換成單獨的命令進行處理,沒有提供很好的批處理能力。
與Spring cloud整合問題,Axon支持與Spring Cloud結合,使用分佈式消息隊列來實現分佈式系統間命令的分發,可是目前沒有比較良好的實現,中文文檔較少,須要進一步研究實施。
Axon的充血模型雖然是一大特點,可是實施起來比較繁瑣,對於簡單的業務實現,貧血模型更加適合。
中文文檔少,上手難度較高,國內使用人少,遇到問題可請教或討論的人少。
將來規劃
從4.0版本開始,Axon已經不止是個框架,而是一個由Axon Framework和Axon Server組成的平臺。目前官方發佈的最新Axon版本已是v4.3.3,本文中的項目基於Axon框架v3.04進行開發,而且是基於單機事件傳播,對於Axon Server機制還未深刻研究使用。另外對於一些高級特性如:與Spring Cloud整合、分佈式命令、分佈式事件、分佈式事務等須要進一步實踐和總結。Axon命令分發支持與配置AMQP協議的MQ(Message Queue)綁定,MQ用於把Event分發到MQ中,採用這種機制能夠針對性的對服務進行更細粒度的拆分,命令分發和處理能夠配置成不一樣的模塊,按照各自吞吐量進行服務部署。此外,分佈式事務一直是個使人頭疼的問題,對於saga的優雅實現須要花費更多的時間進行深刻研究。
領域思想的轉變對面向對象開發語言有着重大的幫助,成熟的架構支持及持久的維護性對於技術選型有着很大的影響,流行的Axon, Akka, Cola等框架勢頭正猛,相信領域思想將來會更深刻人心。
本文分享自微信公衆號 - 愛奇藝技術產品團隊(iQIYI-TP)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。