SpringBoot集成LiteFlow實現(xiàn)輕量級工作流引擎的詳細過程
LiteFlow 是一款專注于邏輯驅(qū)動流程編排的輕量級框架,它以組件化方式快速構(gòu)建和執(zhí)行業(yè)務(wù)流程,有效解耦復(fù)雜業(yè)務(wù)邏輯。通過支持熱加載規(guī)則配置,開發(fā)者能夠即時調(diào)整流程步驟,將復(fù)雜的業(yè)務(wù)如價格計算、下單流程等拆分為獨立且可復(fù)用的組件,從而實現(xiàn)系統(tǒng)的高度靈活性與擴展性。
一、基礎(chǔ)概念
1.1 組件(Component)
LiteFlow 的核心概念是組件,組件是業(yè)務(wù)邏輯的最小單元。每個組件都對應(yīng)一個具體的業(yè)務(wù)操作,例如“發(fā)送郵件”“計算價格”等。組件之間通過規(guī)則進行編排,形成完整的業(yè)務(wù)流程。
liteflow
的組件在規(guī)則文件中即對應(yīng)的節(jié)點,組件對應(yīng)的種類有很多,具體的如下所示:
普通組件
普通組件需要集成的是 NodeComponent
, 可以用在 when 和 then 邏輯中,具體的業(yè)務(wù)需要在 process 中去執(zhí)行。同時在 node 節(jié)點中,可以覆蓋 iaAccess 方法,表示是否進入該節(jié)點執(zhí)行業(yè)務(wù)邏輯,isContinueOnError 判斷在出錯的情況下是否繼續(xù)執(zhí)行下一個組件,默認為 false。 isEnd 方法表示是否終止流程,默認為true。
選擇組件
選擇組件是通過業(yè)務(wù)邏輯來判斷接下來的動作要執(zhí)行哪一個節(jié)點,類似于 Java中的 switch , 在代碼中則需要繼承 NodeSwitchComponent
實現(xiàn) processWitch 方法來處理業(yè)務(wù)。
# flow 規(guī)則表達式 選擇組件 SWITCH(a).to(b, c); # processWitch 表達式需要返回的是 b 或者 c 字符串來執(zhí)行相應(yīng)的業(yè)務(wù)邏輯 # flow 規(guī)則表達式 條件組件 IF(x, a, b);
條件組件
條件組件稱之為 if 組件,返回的結(jié)果是 true 或者 false, 代碼需要集成 NodeIfComponent
重寫 processIf 方法,返回對應(yīng)的業(yè)務(wù)節(jié)點,這個和選擇組件類似。
在官方文檔中,還有次數(shù)循環(huán)組件,條件循環(huán)組件,循環(huán)迭代組件,和退出循環(huán)組件,其應(yīng)用場景比較復(fù)雜,可以使用簡單的普通組件來替代,畢竟是輕量級的規(guī)則引擎,主要作用就是為了編排流程順序,復(fù)雜的場景就升級使用工作流了
1.2 規(guī)則(Rule)
規(guī)則定義了組件之間的執(zhí)行順序和條件。LiteFlow 支持多種規(guī)則文件格式,如 XML、JSON、YAML 等,也支持從本地文件系統(tǒng)、數(shù)據(jù)庫、ZooKeeper、Nacos、Apollo 等多種方式加載規(guī)則。
在我上一段實習(xí)中,就是通過Apollo配置不同場景下的多種任務(wù)編排實現(xiàn)實時生效
# 文件編排, then 代表串行執(zhí)行 when 表示并行執(zhí)行 # 串行編排示例 THEN(a, b, c, d); # 并行編排示例 WHEN(a, b, c); # 串行和并行嵌套結(jié)合 THEN( a, WHEN(b, c, d), e); # 選擇編排示例 SWITCH(a).to(b, c, d); # 條件編排示例 THEN(IF(x, a),b );
1.3 上下文(Context)
上下文用于在組件之間傳遞數(shù)據(jù)。LiteFlow 提供了靈活的上下文機制,可以在流程執(zhí)行過程中存儲和共享數(shù)據(jù)。這里實際上在代碼里定義一個全局變量在整個流程中進行流傳即可
1.4 參數(shù)配置
在 liteflow
中,需要配置的內(nèi)容有規(guī)則文件地址,節(jié)點重試(執(zhí)行報錯時可以進行重試,類似于 spring-retry), 流程并行執(zhí)行線程池參數(shù)配置,流程的請求ID配置。
liteflow: # 規(guī)則文件 失敗重試次數(shù) 打印執(zhí)行日志 監(jiān)控日志 ruleSource : liteflow/*.el.xml retry-count: 0 print-execution-log: true monitor: enable-log: true period: 300000 request-id-generator-class: com.platform.orderserver.config.AppRequestIdGenerator # 上下文的最大數(shù)量槽 slot-size : 10240 # 線程數(shù),默認為64 main-executor-works: 64 # 異步線程最長等待時間 秒 when-max-wait-seconds: 15 # when 節(jié)點全局異步線程池最大線程數(shù) when-max-workers: 16 # when 節(jié)點全局異步線程池隊列數(shù) when-queue-limit: 5120 # 在啟動的時候就解析規(guī)則 parse-on-start: true enable: true
二、基礎(chǔ)用法
2.1 引入依賴
在 Spring Boot 項目中,可以通過以下方式引入 LiteFlow 依賴:
<dependency> <groupId>com.yomahub</groupId> <artifactId>liteflow-spring-boot-starter</artifactId> <version>2.10.6</version> </dependency>
2.2 定義組件
通過 @LiteflowComponent
注解定義組件,并實現(xiàn)具體的業(yè)務(wù)邏輯
@LiteflowComponent("sendEmail") public class SendEmailComponent extends NodeComponent { @Override public void process() throws Exception { System.out.println("發(fā)送郵件"); } }
2.3 編寫規(guī)則文件
在 flow.xml
文件中定義規(guī)則,也可以在代碼中自定義實現(xiàn)EL規(guī)則
xml定義方式
<flow> <chain name="test_flow"> THEN(prepareTrade, grantScore, sendMq, WHEN(sendEmail, sendPhone)); </chain> </flow>
代碼中定義方式
import com.yomahub.liteflow.core.NodeComponent; import com.yomahub.liteflow.el.ELBus; import com.yomahub.liteflow.el.ThenELWrapper; import com.yomahub.liteflow.flow.LiteflowResponse; import com.yomahub.liteflow.slot.DefaultContext; import com.yomahub.liteflow.spring.SpringFlowExecutor; import org.springframework.beans.factory.annotation.Autowired; import java.util.ArrayList; import java.util.List; import java.util.Map; public class LiteFlowDemo { @Autowired private SpringFlowExecutor flowExecutor; public void buildAndExecuteFlow() { // 假設(shè)有一個配置列表,每個配置項對應(yīng)一個處理器 List<Map<String, Object>> configList = new ArrayList<>(); configList.add(Map.of("name", "processor1")); configList.add(Map.of("name", "processor2")); // 假設(shè)有一個處理器名稱映射表 Map<String, String> processorNameMap = Map.of( "processor1", "component1", "processor2", "component2" ); // 構(gòu)建 EL 表達式 ThenELWrapper finalEL = ELBus.then(); for (int i = 0; i < configList.size(); i++) { Map<String, Object> config = configList.get(i); String name = (String) config.get("name"); if (!processorNameMap.containsKey(name)) { System.out.println("No component exists for name: " + name); continue; } String processor = processorNameMap.get(name); finalEL.then(ELBus.node(processor).data("param" + i, "data" + i)); } // 執(zhí)行流程 LiteflowResponse response = flowExecutor.execute2Resp("mainFlow", new DefaultContext()); if (response.isSuccess()) { System.out.println("Flow executed successfully"); } else { System.out.println("Flow execution failed"); } } }
2.4 執(zhí)行流程
通過 FlowExecutor
執(zhí)行流程:
LiteflowResponse response = flowExecutor.execute2Resp("test_flow", new DataRequest());
三、適用場景
LiteFlow 適用于擁有復(fù)雜邏輯的業(yè)務(wù)場景,例如:
- 電商下單流程:包括訂單創(chuàng)建、庫存扣減、支付處理、通知發(fā)送等多個步驟。
- 價格計算引擎:根據(jù)不同的規(guī)則和條件計算商品價格。
- 數(shù)據(jù)處理流程:在數(shù)據(jù)處理中,需要按順序執(zhí)行多個步驟。
四、與 Java 設(shè)計模式的相似性
4.1 策略模式
LiteFlow 的組件類似于策略模式中的策略類,可以根據(jù)不同的規(guī)則動態(tài)選擇執(zhí)行的組件。
4.2 模板方法模式
LiteFlow 的流程定義類似于模板方法模式中的模板方法,定義了業(yè)務(wù)流程的骨架,而具體的組件實現(xiàn)則類似于模板方法中的具體步驟。
4.3 責(zé)任鏈模式
LiteFlow 的組件可以通過規(guī)則進行串聯(lián),類似于責(zé)任鏈模式中的責(zé)任鏈,每個組件負責(zé)處理一部分邏輯。
五、實戰(zhàn)使用
5.1 電商訂單處理案例
假設(shè)在一個電商系統(tǒng)中,訂單完成后需要進行積分發(fā)放、消息發(fā)送,并行發(fā)送短信和郵件??梢酝ㄟ^以下方式實現(xiàn):
xml
<flow> <chain name="orderCompleteFlow"> THEN(prepareTrade, grantScore, sendMq, WHEN(sendEmail, sendPhone)); </chain> </flow>
5.2 動態(tài)規(guī)則更新
LiteFlow 支持熱加載規(guī)則文件,可以在不重啟應(yīng)用的情況下更新規(guī)則。例如,將規(guī)則文件存儲在數(shù)據(jù)庫或配置中心(如 Nacos),修改規(guī)則后可以實時生效。
5.3 監(jiān)控與日志
LiteFlow 提供了詳細的執(zhí)行日志和監(jiān)控功能,可以記錄每個組件的執(zhí)行時間、執(zhí)行結(jié)果等信息,方便排查問題。
5.4 高級特性
- 組件降級:在某些組件執(zhí)行失敗時,可以選擇降級處理。
- 組件繼承:可以通過繼承的方式復(fù)用組件邏輯。
- 組件回滾:在流程執(zhí)行失敗時,可以選擇回滾到之前的步驟。
六、總結(jié)
LiteFlow 是一個功能強大且靈活的規(guī)則引擎框架,適用于復(fù)雜的業(yè)務(wù)流程編排。通過組件化的方式,可以將復(fù)雜的業(yè)務(wù)邏輯拆分為獨立的組件,通過規(guī)則進行編排,實現(xiàn)系統(tǒng)的高度靈活性和擴展性。同時,LiteFlow 提供了豐富的功能,如熱加載、監(jiān)控、日志等,方便開發(fā)者使用。
擴展問題自測
1. LiteFlow 的核心概念是什么?它是如何實現(xiàn)規(guī)則編排的?
LiteFlow 是將復(fù)雜邏輯抽解為一個個可復(fù)用的組件化,通過組件間的自由搭配實現(xiàn)靈活編排。以及利用Apollo或Nacos這些注冊中心進行實時熱更新
組件間的自由搭配是通過規(guī)則鏈實現(xiàn)的
{ "chainId": "recommendChain", "name": "推薦鏈路", "condition": "A > B > C " }
總結(jié):通過 組件化 + 規(guī)則鏈 實現(xiàn)編排,通過注冊中心監(jiān)聽配置變更實現(xiàn)熱更新
2. LiteFlow 規(guī)則節(jié)點(Component)的執(zhí)行機制是怎樣的?支持哪些執(zhí)行模式?
執(zhí)行機制
- 初始化組件,通過@
LiteflowComponent
組件進行組件注冊 - 解析規(guī)則鏈:解析規(guī)則鏈中組件執(zhí)行鏈路
- 執(zhí)行規(guī)則鏈
執(zhí)行模式
- 順序模式:"condition": "A > B > C" ABC順序執(zhí)行
- 并行執(zhí)行:"condition": "A && B && C" 我們的業(yè)務(wù)中,對商品的多路召回就是并行的
- 選擇執(zhí)行 "condition": "A | B | C" 只執(zhí)行多個流程中最先完成的組件
- 條件執(zhí)行 "condition": "A WHEN(B > C)"A 先執(zhí)行,然后判斷是否執(zhí)行 B > C 這條鏈路。
適用于 根據(jù)外部參數(shù)動態(tài)決定執(zhí)行路徑。
- FOR 循環(huán) "condition": "FOR(A, 3)" 適用于 重復(fù)性任務(wù),如輪詢、批量處理等
- WHILE 循環(huán) "condition": "WHILE(A, isContinue())" 適用于 動態(tài)決策的業(yè)務(wù)場景,如輪詢、流式處理
- 失敗處理 "condition": "A THEN(B) A 失敗后,會執(zhí)行 B 作為補償措施。適用于 容錯、降級、回滾等場景
3. LiteFlow 的規(guī)則是如何定義和加載的?
三種方式進行規(guī)則定義與加載
- json格式,在配置文件進行配置
- xml格式,同上
- java代碼中動態(tài)注冊規(guī)則鏈(推薦系統(tǒng)目前使用方式)
4. LiteFlow 規(guī)則流轉(zhuǎn)時,如何保證數(shù)據(jù)在多個節(jié)點之間的傳遞?
LiteFlow實際上也是參考了責(zé)任鏈模式,通過一個全局變量作為上下文進行數(shù)據(jù)流轉(zhuǎn)。LiteFlow里這個上下文變量叫做Slot(上下文容器)
LiteFlow 的 Slot
是一個 線程隔離的上下文容器,用于存儲和管理整個流程中的數(shù)據(jù),類似于 ThreadLocal
,但更適用于 流程級別的數(shù)據(jù)共享。
每次執(zhí)行規(guī)則鏈時,LiteFlow 都會為當(dāng)前執(zhí)行實例創(chuàng)建一個 獨立的 Slot,不同的請求不會相互影響。
LiteFlow 通過 ThreadLocal + 對象池 機制來管理 Slot,確保:
- 每個請求擁有獨立的 Slot 實例,數(shù)據(jù)不會互相污染。
- Slot 復(fù)用機制 提高性能,避免頻繁創(chuàng)建對象。
總結(jié)
LiteFlow 通過 Slot(數(shù)據(jù)槽)在多個節(jié)點之間傳遞數(shù)據(jù),相當(dāng)于流程級別的全局上下文。
Slot 的作用類似責(zé)任鏈模式中的 Context,存儲數(shù)據(jù)供整個規(guī)則鏈?zhǔn)褂谩?/p>
每個請求擁有獨立的 Slot,避免線程安全問題,同時通過對象池優(yōu)化性能。
5. LiteFlow 支持哪些異步執(zhí)行模式?如何處理異步任務(wù)之間的依賴?
到此這篇關(guān)于SpringBoot集成LiteFlow實現(xiàn)輕量級工作流引擎的文章就介紹到這了,更多相關(guān)SpringBoot集成LiteFlow工作流引擎內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Struts2中Action中是否需要實現(xiàn)Execute方法
這篇文章主要介紹了Struts2中Action中是否需要實現(xiàn)Execute方法的相關(guān)資料,需要的朋友可以參考下2016-03-03SpringMVC利用dropzone組件實現(xiàn)圖片上傳
這篇文章主要介紹了SpringMVC利用dropzone組件實現(xiàn)圖片上傳,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02鑒權(quán)認證+aop+注解+過濾feign請求的實例
這篇文章主要介紹了鑒權(quán)認證+aop+注解+過濾feign請求的實例講解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03Java基礎(chǔ)知識精通數(shù)組的內(nèi)存分析
數(shù)組對于每一門編程語言來說都是重要的數(shù)據(jù)結(jié)構(gòu)之一,當(dāng)然不同語言對數(shù)組的實現(xiàn)及處理也不盡相同。Java?語言中提供的數(shù)組是用來存儲固定大小的同類型元素2022-04-04