作者:vivo 網際網路伺服器團隊- Cheng Wangrong
本文是《vivo行銷自動化技術解密》的第4篇文章,分析了在行銷自動化業務引入工作流技術的背景和工作流引擎的介紹,同時介紹了幾種業界流行的開源工作流引擎特點,以及在專案自研開發過程中的設計思路和總結思考。
《vivo行銷自動化技術解密》系列文章:
行銷自動化平臺可以支援不同使用者生命週期的活動旅程策略設定 ,根據使用者觸發的不同活動行為,進行差異化的行銷觸達方案。同時各種型別活動的具體執行過程中也有不同的業務處理流程(比如審批流程和業務流轉)。
業務流程複雜多樣,需求變更頻繁,專案開發過程中會有以下痛點:
如何將業務邏輯從控制流中剝離出來,讓產研人員更聚焦於業務的實現是需要重點解決的問題。而傳統OA領域使用的是久經考驗的業務流程管理解決方案 —— 工作流(Workflow)。工作流是一套工業級的解決方案,由工作流管理聯盟(WfMC)制定了一系列的標準。
工作流(Workflow)—— 對工作流程及其各操作步驟之間業務規則的抽象,將流程中的工作組織邏輯和規則進行建模,交由計算機進行自動處理。
工作流的本質思想是:通過預定義的工作流程模板,對現實活動進行範例化的過程。簡單說就是通過預設的格式或者視覺化設定好流程的模板(比如一種分享活動的執行流程模板),使用時通過該模板構造出一個流程範例物件,通過範例物件完成活動執行跟蹤和回溯。
WfMC工作流管理聯盟為工作流制定了參考模型,其核心就是中間的工作流引擎,工作流引擎提供流程定義工具(介面1)、給使用者提供資訊查詢(介面2)、呼叫外部應用(介面3)、整合其他工作流(介面4)和監控管理(介面5)的能力。 對於大多數工作流產品而言,重點關注的是介面1和介面2的實現。
提供視覺化的流程搭建,流程檢視檢視能力,以及實時觀測任務執行能力。
將公共業務進行元件化,可以支援任務的自由編排,自由搭建出適合的業務的不同流程。
將流程的控制(如流轉、判斷、迴圈、重試等)的任務交由工作流負責,讓使用者聚焦於核心業務邏輯。
對於工作流的型別沒有專門的標準,按照流程任務節點特性可以分為:
順序工作流的執行方式類似一種特定的流程圖,上一個流程任務完成後依次進入下一個流程任務,過程不可逆。
狀態機工作流側重關注的是流程任務的狀態,驅使任務狀態發生變化的因素一般為外部事件,即事件驅動的方式,驅使任務節點從一個狀態執行到另外一個狀態,節點間可逆。
側重於節點的運轉規則,基於業務規則進行工作流程的執行,在處理具有明確目標但「規則」或規範級別不同的各種專案時,規則驅動的工作流非常有用。
可以看到不同型別的工作流不是完全割裂的,狀態機工作流中也可以結合著條件和規則進行操作節點轉換的過程。在軟體開發中,一般會考慮結合狀態機和規則驅動的工作流。
在之前的文章裡面,我們有對狀態機和工作流引擎做過一次簡單的對比,事實上,兩者之間並不是一個完全對等的概念:
瞭解了工作流的基本特點和使用場景之後,我們來看一下比較流行的開源工作流引擎。
迴歸工作流的本質, 工作流是通過預定義的流程模板,對現實活動進行範例化的過程。一個基本的工作流引擎主要包括三大核心部分:
根據業務規則和邏輯,建立流程模板,設定每一個節點的操作和變更路徑。基於模板建立,可以延伸出流程設計器、外掛式節點,多樣化的模板檔案格式、模板持久化等。
根據流程模板,建立一個流程範例,流程模板和流程範例的關係類似類和物件的關係。比如說工單系統管理員定義好一個審批流模板(流程模板),使用者點選建立一個工單(流程範例)。基於流程範例釋出,又可以延伸出範例實時觀測,節點變遷記錄回溯,範例狀態持久化,失敗重試,事務控制等。
建立好流程範例之後,流程範例只需要按照流程模板的定義獨立執行各自範例的任務,不同的範例之間互不影響,完成各自範例的生命週期。
① 應用容器啟動時,載入流程引擎環境設定,包括解析器構造,流程引擎上下文,流程定義檔案路徑等。
② 讀取定好的流程定義檔案,進行流程節點解析,構建好執行上下文,將流程節點放到記憶體快取中。
③ 業務側進行流程建立,啟動一個新的流程範例,同時將業務流程和流程範例進行繫結。
④ 執行流程範例各個節點,將每個流程節點進行持久化儲存。
① 引擎核心服務。
引擎操作的主要對外介面,包括啟動流程範例,和獲取相關流程定義模板,流程範例,流程節點的服務。
public interface FlowEngine {
/**
* 根據流程定義key,參數列啟動流程範例
*
*/
FlowInstance startInstance(String processDefKey, Map<String, Object> args);
/**
* 根據流程定義主鍵ID,參數列執行流程任務(推動流程自動流轉)
* 統一事務控制
*/
void execInstance(Long instanceId, Map<String, Object> args) throws FlowAuthorityException;
/**
* 獲取流程定義process服務
*
*/
ProcessService process();
/**
* 獲取流程範例服務
*
*/
InstanceService instance();
/**
* 獲取任務節點服務
*
*/
TaskService task();
}
② 流程定義服務。
主要是針對流程定義模板的建立和釋出,可以根據具體的實現類來支援不同的建立方式。
public interface ProcessService {
/**
* 建立流程定義模板
*
*/
void create(String definition);
/**
* 釋出流程定義模板
*
*/
void deploy(String fileName);
/**
* 獲取流程key對應的流程定義
*/
FlowProcess getProcessByDefKey(String processDefKey);
}
③ 流程範例服務。
提供流程範例建立持久化和流程範例執行的入口。
public interface InstanceService {
/**
* 建立流程範例
*
*/
FlowInstance createInstance(FlowProcess process, Map<String, Object> args);
/**
* 執行流程範例
*
* @param instanceId 流程範例id
*/
void exec(Long instanceId);
/**
* 根據id獲取流程範例
*
* @param instanceId
* @return
*/
FlowInstance getById(Long instanceId);
}
④ 流程任務節點服務。
提供流程節點具體每個任務的建立和查詢。
public interface TaskService {
/**
* 根據任務模型、執行物件建立新的任務
*
*/
FlowTask createTask(TaskModel taskModel, Execution execution);
/**
* 完成任務
*
*/
FlowTask complete(Long taskId, Map<String, Object> args);
/**
* 獲取流程範例中正在進行的任務
*
*/
FlowTask getActiveTask(Long instanceId);
/**
* 獲取流程範例上一個已完成的任務
*
*/
FlowHistTask getLastDoneTask(Long instanceId);
}
其中核心的方法就是
FlowEngine#startInstanceByKey,啟動流程範例。基於流程定義,建立一個流程範例物件。
FlowEngine#execInstance,執行流程範例任務,通過傳入的上下文引數(操作人,操作變數等),按照流程定義的節點任務,推進流程範例的自動流轉。
由於目前設計是在應用啟動時對所有的流程定義檔案進行載入和解析,流程定義檔案過多時會影響應用啟動速度,可以通過多執行緒解析和懶載入(使用時解析)兩種方式進行優化。
由於業務流程不是一成不變的,在專案發展過程中會不斷進行迭代,需要對前面不同的流程進行相容。
將基礎服務進行提取公用,以支援繪製不同流程的外掛化和編排能力。
對流程任務節點執行情況進行埋點上報,系統自動進行監測告警。
本文分析了引入工作流引擎的背景,驅使業務邏輯從控制流中剝離出來,讓產研團隊更聚焦於業務,解決研發效率低的問題。
工作流的本質思想是通過預定義的工作流程模板,對現實活動進行範例化的過程。一般需要具備流程視覺化、業務可編排複用、 業務和控制分離的基本能力。一般常見的工作流分為順序工作流、狀態機工作流和規則驅動工作流,開源工作流框架中最常見的是狀態機工作流,利用事件驅動的方式,驅使流程運轉。
同時簡單介紹了業界比較流行的幾種開源工作流引擎的特點,結合開源工作流引擎的特點的問題,並且針對多樣化和迭代頻繁的業務流程, 以工作流的本質思想為出發點,我們自研了一套輕量級的工作流引擎,分享了在實踐過程中的設計思路和總結思考。