作者:李玉亮
JDEasyFlow是企業金融研發部自研的通用流程編排技術組件,適用于服務編排、作業流、審批流等場景,該組件已開源(https://github.com/JDEasyFlow/jd-easyflow),目前在部門的內部業務系統和科技輸出系統中廣泛應用,其他部門也有使用,
它的特點是簡單、靈活、易擴展,開發人員一般30分鐘可入門上手,半天可掌握其原理,它分為一個核心模塊和若干擴展模塊,模塊之間松耦合,開發使用時可按需選擇、快速集成、漸進式應用,同時支持JSON內置規范和BPMN規范,它的實作原理也有其特色,后面有介紹,
支持的場景功能
節點流轉型別
支持順序流轉、條件流轉、回圈流轉等,
節點功能型別
支持腳本節點、用戶節點和訊息節點,
? 腳本節點:節點執行時運行一段代碼腳本
? 用戶節點:根據用戶的操作指令觸發節點執行
? 訊息節點:接收訊息后觸發節點執行
節點串并型別
支持串行執行、并行執行、串并組合執行等,
流程互動場景
支持單次互動一次執行多節點、多次互動一次執行一節點、多次互動一次執行多節點等,
子流程場景
JDEasyFlow支持子流程的場景,可將把復雜的流程節點拆分為子流程,便于業務邏輯抽象,
審批流程場景
JDEasyFlow提供了流程任務審批的能力;常用的審批、撤銷、駁回、會簽、加簽等功能都可支持;內置了簡單的動態表單,既支持從頁面發起和操作流程任務,也支持API的方式,京東OA審批系統也有對接,
功能架構
整體功能架構
JDEasyFlow的功能架構如下圖,功能模塊之間松耦合, 開發時可按需選擇、快速集成、漸進式應用,最簡單的使用方式為只在業務應用端引入jar包使用流程引擎,如果需要流程可視化功能,可集成BPMN規范模塊,如果還需要流程實體持久化、流程定義持久化等更豐富功能,則可以集成其他相關模塊,
流程引擎模塊
JDEasyFlow的核心模塊,此模塊提供了基于JSON格式的JDEasyFlow規范進行流程編排的能力,其他模塊均基于該模塊擴展,相當于流程執行的發動機、CPU,該功能模塊為獨立組件,無資料庫依賴,應用中引入jar包便可使用,
BPMN規范模塊
提供了基于BPMN規范進行流程定義和可視化的能力,流程可視化基于[bpmn-js](https://bpmn.io/),其本質為提供了將BPMN格式流程定義轉換為JDEasyFlow格式的能力,該模塊為獨立組件,僅依賴流程引擎模塊,無資料庫和服務依賴,應用中引入jar包便可使用,
目前可支持常用的BPMN元素:
? 任務:腳本任務、用戶任務、訊息任務
? 事件:開始事件、結束事件、訊息接收事件
? 網關:排他網關、并行網關、包容網關
流程定義和實體管理模塊
流程定義模塊支持流程定義的中心化、版本化管理,流程實體模塊支持流程實體的持久化和生命周期管理,該功能依賴資料庫,有服務端和ERP管理端,
任務/審批模塊
支持任務生成、任務分配等功能,常用的審批、撤銷、駁回、會簽、加簽等功能都可支持,該功能依賴資料庫,有服務端和ERP管理端,
系統架構
整體系統架構
JDEasyFlow的完整系統架構如下,主要有三個端:業務應用端、流程服務端、流程管理端,三個端可部署在單體應用中,也可分開部署,
中間件依賴
· 關系型資料庫(如Mysql)
· 快取(如Redis或R2M)
· 服務通訊框架(如Java API呼叫或Http呼叫或JSF呼叫)
資料庫資料模型比較簡單清晰,見下圖:
性能說明
· 如果僅是服務編排場景,則流程的執行僅依賴記憶體和CPU,并且是在流程客戶端執行,性能上依賴于客戶端服務器的性能,普通筆記本實測1秒可執行一個流程請求的1w+個節點,1秒可執行1萬+次含1個節點的流程請求
· 如果需要流程狀態管理和流程持久化功能,流程引擎在執行時會到流程服務端查詢和保存流程實體和流程節點的狀態,性能上主要依賴于資料庫的查詢和插入效率
· 對于流程任務審批功能,流程的任務審批流轉是在服務端執行,一方面取決于流程服務端的計算性能,另一方面同樣取決于資料庫的查詢和插入效率
可伸縮性說明
· 流程引擎屬于無狀態,可隨應用實體線性伸縮
· 流程服務端應用實體支持線性擴展
· 流程資料庫可通過分庫分表的方式支持大資料量的增長
實踐建議
在具體實踐中,建議部署統一的流程中心(見下圖),對流程定義統一管理,各系統的應用只需集成流程客戶端jar包進行流程節點開發和流程呼叫便可,如果系統只使用任務審批的功能,則只需要通過API和訊息與流程中心互動便可,
使用示例
流程引擎使用示例
在原始碼的test目錄下有quickstart測驗用例(easyflow\easyflow-flow\src\test\java\com\jd\easyflow\flow\quickstart\QuickStartTest.java),可直接運行或除錯以了解使用方式和運行原理,具體實踐步驟如下:
1、代碼中引入easyflow-flow jar包,以maven為例:
<dependency>
<groupId>com.jd.easyflow</groupId>
<artifactId>easyflow-flow</artifactId>
<version>{替換為最新版本}</version>
</dependency>
2、撰寫流程定義檔案,以node001->node002→node003的執行順序為例:
{"id": "quickstart_001", "name": "Quick Start 001",
"nodes": [
{"id": "node001","name": "Node001","action": {"createExp": "new com.jd.easyflow.flow.quickstart.QuickStart001Node01Action()"},"start": true,"post": {"to": "node002"}},
{"id": "node002","name": "Node002","action": {"createExp": "new com.jd.easyflow.flow.quickstart.QuickStart002Node01Action()"},"post": {"to": "node003"}},
{"id": "node003","name": "Node003","action": {"createExp": "new com.jd.easyflow.flow.quickstart.QuickStart003Node01Action()"}}
]
}
其中QuickStart001Node01Action等為java節點動作類,完整的流程定義配置項可見: https://github.com/JDEasyFlow/jd-easyflow/wiki/Flow-engine-usage (公網)
3、撰寫應用啟動時加載流程引擎的代碼
FlowEngineImpl flowEngine = new FlowEngineImpl();
flowEngine.setFlowPath("classpath:flow/quickstart/quickstart_001.json");
flowEngine.init();
Spring環境可直接定義FlowEngineImpl bean.
4、撰寫具體流程呼叫執行的代碼
FlowParam param = new FlowParam("quickstart_001");
FlowResult result = flowEngine.execute(param);
完整測驗用例的執行結果列印如下:
[main ] INFO FlowEngineImpl - Start parsing definition files:easyflow-flow/target/test-classes/flow/quickstart/quickstart_001.json
[main ] INFO FlowEngineImpl - SART EXECUTE FLOW, flowId:quickstart_001 nodeIds:null
[main ] INFO BaseFlowRunner - EXECUTE NODE:node001
[main ] INFO QuickStart001Node01Action - Execute Node 001
[main ] INFO BaseFlowRunner - NEXT NODES:node002
[main ] INFO BaseFlowRunner - EXECUTE NODE:node002
[main ] INFO QuickStart002Node01Action - Execute Node 002
[main ] INFO BaseFlowRunner - NEXT NODES:node003
[main ] INFO BaseFlowRunner - EXECUTE NODE:node003
[main ] INFO QuickStart003Node01Action - Execute Node 003
[main ] INFO BaseFlowRunner - NEXT NODES:
[main ] INFO QuickStartTest - Execute finish, current node is:node003
BPMN模塊使用示例
打開easyflow-flow-bpmn/BPMNDesigner.html流程設計器. 點擊匯入按鈕,匯入easyflow-flow-bpmn/src/test/resources/flow/quickstart/quickstart_001.bpmn檔案,可在設計器中看到和以上JSON定義等價的BPMN流程定義.
代碼集成使用時只需要將FlowEngineImpl的flowParser設定為BpmnFlowParser.
更多
以上只是流程引擎和BPMN模塊的簡單使用示例,JDEasyFlow還包含其他模塊、可支持很多的配置項和使用場景,更多使用可見最后的對接使用介紹.
實作原理
目前市面上的流程編排組件基本都是基于圖(邊和頂點)結構的,而本組件是參考了計算機指令執行模型而實作,借鑒了程式計數器的實作原理,引擎內部通過類似程式計數器(PC)的待執行節點堆疊來維護后繼節點;可以理解為是一種高級業務編程語言,它同時也是圖靈完備的,
流程引擎核心模型名詞只有一個:節點(Node),節點的功能為執行邏輯并輸出后續節點 ,
開發態可定義有限的節點,通過每個節點與其后續節點連接形成有向圖;運行態按規則邏輯進行節點流轉,支持并行執行,支持順序、條件或回圈,支持fork-join,
概念:
? 流程:一個業務流程的抽象
? 節點:流程的組成單位,一個節點能夠執行節點動作同時可回傳后繼節點
節點內部構件:
節點內部構件的組成是可自定義的,流程引擎提供了預設實作,其內部構件包括了前處理器(PreHandler)、節點動作(NodeAction)、后處理器(PostHandler)
? 前處理器:判斷該節點是否可以執行動作
? 節點動作:真實的業務功能處理
? 后處理器:負責計算后續節點
流程引擎執行邏輯
流程引擎有一個或多個流程觸發節點,流程觸發后執行如下邏輯:
1. 初始化流程背景關系
2. 得到流程起始節點ID,放入執行堆疊
3. 如果執行堆疊為空,則回傳,否則執行當前節點
-
預檢查
-
執行Action
-
計算后繼節點ID并回傳
4. 將后繼節點放入執行堆疊,從堆疊中取出待執行節點,跳到第3步
因此JDEasyFlow整體的特色為簡單:
? 模型簡單:核心模型概念就是節點的流轉
? 擴展簡單:提供了監聽器、過濾器功能,方便橫向切面;節點支持自定義實作
? 定義簡單:只需要通過JSON進行節點流轉邏輯配置便可,也支持BPMN格式
? 運行簡單:代碼呼叫流程引擎,傳入流程ID和業務引數便可
? 使用簡單:引入組件包便可使用,比較輕量
適用場景和對接使用說明
適用場景
理論上JDEasyFlow可滿足任何流程場景,它主要可解決三類問題:
? 流程可編排:將業務流程抽象為軟體流程,保證軟體是現實的真實反映;不同場景可定義不同流程,且流程易修改
? 功能松耦合:將業務節點抽象為軟體流程節點,一方面實作功能的松耦合,另一方面實作節點的可復用
? 流程可視化:所見即所得,方便業務產品人員和軟體研發人員基于同一語言的交流,也便于流程監控
在實際軟體系統開發程序中,如果有如下訴求,可考慮使用流程編排:
? 業務流程是有明顯的多個節點組成
? 希望流程可靈活變更
? 業務流程級別比程式流程高一層,在編程語言級別難以聚合和治理(如一個流程即需要前臺操作,又有外系統參與,又有后臺操作,在實作上入口分散)
對接使用
JDEasyFlow的所有檔案可見: https://github.com/JDEasyFlow/jd-easyflow/wiki (公網)
歡迎大家對接使用,有相關使用問題可聯系: [email protected]
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/538408.html
標籤:架構設計
