LiteFlow 是一款專注于邏輯驅動流程編排的輕量級框架,它以組件化方式快速構建和執行業務流程,有效解耦復雜業務邏輯。通過支持熱加載規則配置,開發者能夠即時調整流程步驟,將復雜的業務如價格計算、下單流程等拆分為獨立且可復用的組件,從而實現系統的高度靈活性與擴展性。
一、基礎概念
1.1 組件(Component)
LiteFlow 的核心概念是組件,組件是業務邏輯的最小單元。每個組件都對應一個具體的業務操作,例如“發送郵件”“計算價格”等。組件之間通過規則進行編排,形成完整的業務流程。
liteflow
的組件在規則文件中即對應的節點,組件對應的種類有很多,具體的如下所示:
- 普通組件
普通組件需要集成的是 NodeComponent
, 可以用在 when 和 then 邏輯中,具體的業務需要在 process 中去執行。同時在 node 節點中,可以覆蓋 iaAccess 方法,表示是否進入該節點執行業務邏輯,isContinueOnError 判斷在出錯的情況下是否繼續執行下一個組件,默認為 false。 isEnd 方法表示是否終止流程,默認為true。
- 選擇組件
選擇組件是通過業務邏輯來判斷接下來的動作要執行哪一個節點,類似于 Java中的 switch , 在代碼中則需要繼承 NodeSwitchComponent
實現 processWitch 方法來處理業務。
# flow 規則表達式 選擇組件
SWITCH(a).to(b, c);
# processWitch 表達式需要返回的是 b 或者 c 字符串來執行相應的業務邏輯
# flow 規則表達式 條件組件
IF(x, a, b);
- 條件組件
條件組件稱之為 if 組件,返回的結果是 true 或者 false, 代碼需要集成 NodeIfComponent
重寫 processIf 方法,返回對應的業務節點,這個和選擇組件類似。
在官方文檔中,還有次數循環組件,條件循環組件,循環迭代組件,和退出循環組件,其應用場景比較復雜,可以使用簡單的普通組件來替代,畢竟是輕量級的規則引擎,主要作用就是為了編排流程順序,復雜的場景就升級使用工作流了
1.2 規則(Rule)
規則定義了組件之間的執行順序和條件。LiteFlow 支持多種規則文件格式,如 XML、JSON、YAML 等,也支持從本地文件系統、數據庫、ZooKeeper、Nacos、Apollo 等多種方式加載規則。
在我上一段實習中,就是通過Apollo配置不同場景下的多種任務編排實現實時生效
# 文件編排, then 代表串行執行 when 表示并行執行
# 串行編排示例
THEN(a, b, c, d);
# 并行編排示例
WHEN(a, b, c);
# 串行和并行嵌套結合
THEN( a, WHEN(b, c, d), e);
# 選擇編排示例
SWITCH(a).to(b, c, d);
# 條件編排示例
THEN(IF(x, a),b );
1.3 上下文(Context)
上下文用于在組件之間傳遞數據。LiteFlow 提供了靈活的上下文機制,可以在流程執行過程中存儲和共享數據。這里實際上在代碼里定義一個全局變量在整個流程中進行流傳即可
1.4 參數配置
在 liteflow
中,需要配置的內容有規則文件地址,節點重試(執行報錯時可以進行重試,類似于 spring-retry), 流程并行執行線程池參數配置,流程的請求ID配置。
liteflow:# 規則文件 失敗重試次數 打印執行日志 監控日志ruleSource : liteflow/*.el.xmlretry-count: 0print-execution-log: truemonitor:enable-log: trueperiod: 300000request-id-generator-class: com.platform.orderserver.config.AppRequestIdGenerator# 上下文的最大數量槽slot-size : 10240# 線程數,默認為64main-executor-works: 64# 異步線程最長等待時間 秒when-max-wait-seconds: 15# when 節點全局異步線程池最大線程數when-max-workers: 16# when 節點全局異步線程池隊列數when-queue-limit: 5120# 在啟動的時候就解析規則parse-on-start: trueenable: true
二、基礎用法
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
注解定義組件,并實現具體的業務邏輯
@LiteflowComponent("sendEmail")
public class SendEmailComponent extends NodeComponent {@Overridepublic void process() throws Exception {System.out.println("發送郵件");}
}
2.3 編寫規則文件
在 flow.xml
文件中定義規則,也可以在代碼中自定義實現EL規則
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 {@Autowiredprivate SpringFlowExecutor flowExecutor;public void buildAndExecuteFlow() {// 假設有一個配置列表,每個配置項對應一個處理器List<Map<String, Object>> configList = new ArrayList<>();configList.add(Map.of("name", "processor1"));configList.add(Map.of("name", "processor2"));// 假設有一個處理器名稱映射表Map<String, String> processorNameMap = Map.of("processor1", "component1","processor2", "component2");// 構建 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));}// 執行流程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 執行流程
通過 FlowExecutor
執行流程:
LiteflowResponse response = flowExecutor.execute2Resp("test_flow", new DataRequest());
三、適用場景
LiteFlow 適用于擁有復雜邏輯的業務場景,例如:
- 電商下單流程:包括訂單創建、庫存扣減、支付處理、通知發送等多個步驟。
- 價格計算引擎:根據不同的規則和條件計算商品價格。
- 數據處理流程:在數據處理中,需要按順序執行多個步驟。
四、與 Java 設計模式的相似性
4.1 策略模式
LiteFlow 的組件類似于策略模式中的策略類,可以根據不同的規則動態選擇執行的組件。
4.2 模板方法模式
LiteFlow 的流程定義類似于模板方法模式中的模板方法,定義了業務流程的骨架,而具體的組件實現則類似于模板方法中的具體步驟。
4.3 責任鏈模式
LiteFlow 的組件可以通過規則進行串聯,類似于責任鏈模式中的責任鏈,每個組件負責處理一部分邏輯。
五、實戰使用
5.1 電商訂單處理案例
假設在一個電商系統中,訂單完成后需要進行積分發放、消息發送,并行發送短信和郵件。可以通過以下方式實現:
xml
<flow><chain name="orderCompleteFlow">THEN(prepareTrade, grantScore, sendMq, WHEN(sendEmail, sendPhone));</chain>
</flow>
5.2 動態規則更新
LiteFlow 支持熱加載規則文件,可以在不重啟應用的情況下更新規則。例如,將規則文件存儲在數據庫或配置中心(如 Nacos),修改規則后可以實時生效。
5.3 監控與日志
LiteFlow 提供了詳細的執行日志和監控功能,可以記錄每個組件的執行時間、執行結果等信息,方便排查問題。
5.4 高級特性
- 組件降級:在某些組件執行失敗時,可以選擇降級處理。
- 組件繼承:可以通過繼承的方式復用組件邏輯。
- 組件回滾:在流程執行失敗時,可以選擇回滾到之前的步驟。
六、總結
LiteFlow 是一個功能強大且靈活的規則引擎框架,適用于復雜的業務流程編排。通過組件化的方式,可以將復雜的業務邏輯拆分為獨立的組件,通過規則進行編排,實現系統的高度靈活性和擴展性。同時,LiteFlow 提供了豐富的功能,如熱加載、監控、日志等,方便開發者使用。
擴展問題自測
1. LiteFlow 的核心概念是什么?它是如何實現規則編排的?
LiteFlow 是將復雜邏輯抽解為一個個可復用的組件化,通過組件間的自由搭配實現靈活編排。以及利用Apollo或Nacos這些注冊中心進行實時熱更新
組件間的自由搭配是通過規則鏈實現的
{"chainId": "recommendChain","name": "推薦鏈路","condition": "A > B > C "
}
總結:通過 組件化 + 規則鏈 實現編排,通過注冊中心監聽配置變更實現熱更新
2. LiteFlow 規則節點(Component)的執行機制是怎樣的?支持哪些執行模式?
- 執行機制
- 初始化組件,通過@
LiteflowComponent
組件進行組件注冊 - 解析規則鏈:解析規則鏈中組件執行鏈路
- 執行規則鏈
- 執行模式
- 順序模式:"condition": "A > B > C" ABC順序執行
- 并行執行:"condition": "A && B && C" 我們的業務中,對商品的多路召回就是并行的
- 選擇執行 "condition": "A | B | C" 只執行多個流程中最先完成的組件
- 條件執行 "condition": "A WHEN(B > C)"
A
先執行,然后判斷是否執行B > C
這條鏈路。
適用于 根據外部參數動態決定執行路徑。
- FOR 循環 "condition": "FOR(A, 3)" 適用于 重復性任務,如輪詢、批量處理等
- WHILE 循環 "condition": "WHILE(A, isContinue())" 適用于 動態決策的業務場景,如輪詢、流式處理
- 失敗處理 "condition": "A THEN(B)
A
失敗后,會執行B
作為補償措施。適用于 容錯、降級、回滾等場景
3. LiteFlow 的規則是如何定義和加載的?
三種方式進行規則定義與加載
- json格式,在配置文件進行配置
- xml格式,同上
- java代碼中動態注冊規則鏈(推薦系統目前使用方式)
4. LiteFlow 規則流轉時,如何保證數據在多個節點之間的傳遞?
LiteFlow實際上也是參考了責任鏈模式,通過一個全局變量作為上下文進行數據流轉。LiteFlow里這個上下文變量叫做Slot(上下文容器)
LiteFlow 的 Slot
是一個 線程隔離的上下文容器,用于存儲和管理整個流程中的數據,類似于 ThreadLocal
,但更適用于 流程級別的數據共享。
每次執行規則鏈時,LiteFlow 都會為當前執行實例創建一個 獨立的 Slot,不同的請求不會相互影響。
LiteFlow 通過 ThreadLocal + 對象池 機制來管理 Slot,確保:
- 每個請求擁有獨立的 Slot 實例,數據不會互相污染。
- Slot 復用機制 提高性能,避免頻繁創建對象。
總結
LiteFlow 通過 Slot(數據槽)在多個節點之間傳遞數據,相當于流程級別的全局上下文。
Slot 的作用類似責任鏈模式中的 Context,存儲數據供整個規則鏈使用。
每個請求擁有獨立的 Slot,避免線程安全問題,同時通過對象池優化性能。