Spring Boot + liteflow 規則引擎,太香了!

作者:豫州牧
鏈接:https://juejin.cn/post/7296771770098745344

1、前言

在日常的開發過程中,經常會遇到一些串行或者並行的業務流程問題,而業務之間不必存在相關性。

在這樣的場景下,使用策略和模板模式的結合可以很好的解決這個問題,但是使用編碼的方式會使得文件太多,在業務的部分環節可以這樣操作,在項目角度就無法一眼洞穿其中的環節和邏輯。在本文中,將引入規則引擎從全局角度來解決這個問題,這就是今天要介紹的主角 liteflow

2、liteflow 規則引擎

liteflow 是一個輕巧而且強大的規則引擎,能夠實現開箱即用,可以在短時間內就可以完成複雜的規則編排,下圖是 liteflow 的整體架構。liteflow 支持較多的規則文件格式,比如 xml/json/yaml, 對於規則文件的存儲方式可以有sql/zk/nacos/apollo 等。

liteflow 的使用是從獲取上下文開始的,通過數據上下文來解析對應的規則文件,通過 liteflow 執行器來執行對應的鏈路,每個鏈路上都有需要執行的業務 node(即節點組件,可以支持多種語言腳本, groovy/js/python/lua等), 各個業務node 之間是獨立的。

liteflow 對應的官方網址和依賴如下所示:

# liteflow 規則引擎官方網址
https://liteflow.yomahub.com
# springboot 集成 liteflow
<dependency>
    <groupId>com.yomahub</groupId>
    <artifactId>liteflow-spring-boot-starter</artifactId>
    <version>2.10.6</version>
</dependency>

liteflow 可以支持如下所示的複雜流程

此外,liteflow 可以支持熱部署,可以實時替換或者增加節點,即修改規則文件後可以實時生效。

3、liteflow 的使用方法

3.1 組件

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 方法,返回對應的業務節點,這個和選擇組件類似。

在官方文檔中,還有次數循環組件,條件循環組件,循環迭代組件,和退出循環組件,作者認爲其應用場景比較複雜,可以使用簡單的普通組件來替代,畢竟是輕量級的規則引擎,主要作用就是爲了編排流程順序,複雜的場景就升級使用工作流了,所以這裏只介紹以上三種組件。

3.2 EL 規則文件

規則文件的編寫和組件的使用是對應的,這裏使用xml 的形式來編寫。

# 文件編排, 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 );

3.3 數據上下文

liteflow 中,數據上下文的概念非常重要,上下文對象起到參數傳遞的作用,因爲不同業務需要的輸入輸出參數是不同的,所以上下文非常的重要。

# 執行流程時,需要傳遞el文件,初始化參數以及上下文對象,這裏的上下文可以設置多個
LiteflowResponse response = flowExecutor.execute2Resp("chain1", 流程初始參數, CustomContext.class);

因爲上下文傳入的是一個 class 類型參數,流程參數是可以傳入參數的,一般情況下是在第一個節點中,將傳入參數設置到上下文對象中。

Spring Boot 基礎就不介紹了,推薦看這個實戰項目:

https://github.com/javastacks/spring-boot-best-practice

3.4 參數配置

liteflow 中,需要配置的內容有規則文件地址,節點重試(執行報錯時可以進行重試,類似於 spring-retry), 流程並行執行線程池參數配置,流程的請求ID配置。

liteflow:
  # 規則文件 失敗重試次數 打印執行日誌 監控日誌
  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
  # 上下文的最大數量槽
  slot-size : 10240
  # 線程數,默認爲64
  main-executor-works: 64
  # 異步線程最長等待時間 秒
  when-max-wait-seconds: 15
  # when 節點全局異步線程池最大線程數
  when-max-workers: 16
  # when 節點全局異步線程池隊列數
  when-queue-limit: 5120
  # 在啓動的時候就解析規則
  parse-on-start: true
  enable: true

4、業務實踐

之前介紹了 liteflow 的一些概念,在這裏結合一些業務場景來進行演示:

# 主要使用電商場景的應用,訂單完成後,進行積分的發放,消息發送,同時並行發送短信和郵件。
<?xml version="1.0" encoding="UTF-8"?>
<flow>
    <chain name="test_flow">
        THEN(
           prepareTrade, grantScore, sendMq, WHEN(sendEmail, sendPhone)
        );
    </chain>
</flow>

在訂單完成之後異步執行,傳遞參數並執行相應的規則流程。

在正式處理業務流程之前,需要先進行數據的預處理,將流程入參轉轉換成上下文對象,方便參數的傳遞和設置。

在具體的業務處理環節,以積分發放爲例,可以獲取上下文對象進行業務操作,同時也可以重寫 isAccess 方法,來判斷是否處理該節點。

如上圖所示,具體的業務流程都可以抽象成一個 node 節點,存放在 test_flow.el.xml 中進行執行,其它的代碼都和積分發放類似,這裏就不再贅述,可以參見代碼。

5、總結

liteflow 中的絕大部分是在啓動時完成的,包括規則解析、註冊組件以及組裝信息,其執行性能很高,同時也可以打印每個業務環節的耗時以及統計信息。

在本文中,介紹了 liteflow 的基本概念,以及具體的使用方法,具體的代碼已經上傳到 github:https://github.com/thedestiny/springboot-auth/

更多文章推薦:

1.Spring Boot 3.x 教程,太全了!

2.2,000+ 道 Java面試題及答案整理(2024最新版)

3.免費獲取 IDEA 激活碼的 7 種方式(2024最新版)

覺得不錯,別忘了隨手點贊+轉發哦!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章