工作流引擎概要分析


一、什么是工作流

工作流,是把業務之間的各個步驟以及規則進行抽象和概括性的描述。使用特定的語言為業務流程建模,讓其運行在計算機上,並讓計算機進行計算和推動。工作流是復雜版本的狀態機。  

上圖為工作流退化為基礎狀態機的例子,小明的狀態非常簡單,站立->走路->跑步->走路->站立,無限循環,如果讓我們實現小明的狀態切換,那么我們只需要用一個字段來記錄小明當前的狀態就好了。 

而對於復雜的狀態或者狀態維度增加且狀態流轉的條件極為復雜,可能單純用字段記錄狀態的實現方式就會不那么理想。 

如上圖所示,現在交給小明的選擇就多了起來,當小明獲得金錢的時候,他會根據金錢數額的大小來判斷接下來該如何行動,如果數額小於等於3000,那么他決定買一個新手機就夠了,如果數額小於等於30萬,那么小明就決定去學習一下理財,好好利用這筆錢,但如果小明獲得的金錢數量超過了30萬,他就決定購置一套房屋,但購置房屋的流程是復雜的,小明決定同時完成交首付和貸款的手續。

其實這個流程還不算特別復雜,但到目前為止,單純用一個字段來表明狀態已經無法滿足要求了。

工作流解決的痛點在於,解除業務宏觀流程和微觀邏輯的耦合,讓熟悉宏觀業務流程的人去制定整套流轉邏輯,而讓專業的人只需要關心他們應當關心的流程節點,就好比大家要一起修建一座超級體育場,路人甲只需要關心他身邊的這一堆磚是怎么堆砌而非整座建築。 

那么工作流有什么不能解決的問題呢? 

工作流是一個固定好的框架,大家就按照這個框架來執行流程就行了,但某些情況他本身沒有流轉順序的要求,比如:小明每天需要做作業,做運動以及玩游戲,它們之間沒有關聯性無法建立流程,但可以根據每一項完成的狀態決定今天的任務是否完結,這種情況我們需要使用CMMN來建模,它就是專門針對這種情況而設計的,但今天我們不講這個,而是講講BPMN協議。

BPMN2.0協議 

對於業務建模,我們需要一種通用的語言來描繪,這樣在溝通上和實現上會降低難度,就像中文、英文一樣,BPMN2.0便是一種國際通用的建模語言,他能讓自然人輕松閱讀,更能被計算機所解析。

協議中元素的主要分類為,事件-任務-連線-網關。 

一個流程必須包含一個事件(如:開始事件)和至少一個結束(事件)。其中網關的作用是流程流轉邏輯的控制。任務則分很多類型,他們各司其職,所有節點均由連線聯系起來。 

下面我就以每種類型的節點簡單地概括一下其作用。

網關: 

 

互斥網關(Exclusive Gateway),又稱排他網關,他有且僅有一個有效出口,可以理解為if......else if...... else if......else,就和我們平時寫代碼的一樣。 

並行網關(Parallel Gateway),他的所有出口都會被執行,可以理解為開多線程同時執行多個任務。 

包容性網關(Inclusive Gateway),只要滿足條件的出口都會執行,可以理解為 if(......) do, if (......) do, if (......) do,所有的條件判斷都是同級別的。 

任務: 

 

BPMN2.0協議的所有任務其實是從一個抽象任務派生而來的,抽象任務會有如下行為:

  1. 當流程流轉到該任務時,應該做些什么?
  2. 當該任務獲得信號(signal)的時候,它是否可以繼續向下流轉,而任務獲得信號的這個動作我們稱為Trigger。 

利用如上的抽象行為,我們來解釋一些比較常見且具有代表性的任務類型。 

人工任務(User Task),它是使用得做多的一種任務類型,他自帶有一些人工任務的變量,例如簽收人(Assignee),簽收人就代表該任務交由誰處理,我們也可以通過某個特定或一系列特定的簽收人來查找待辦任務。利用上面的行為解釋便是,當到達User Task節點的時候,節點設置Assignee變量或等待設置Assignee變量,當任務被完成的時候,我們使用Trigger來要求流程引擎退出該任務,繼續流轉。 

服務任務(Service Task),該任務會在到達的時候執行一段自動的邏輯並自動流轉。從“到達自動執行一段邏輯”這里我們就可以發現,服務任務的想象空間就可以非常大,我們可以執行一段計算,執行發送郵件,執行RPC調用,而使用最廣泛的則為HTTP調用,因為HTTP是使用最廣泛的協議之一,它可以解決大部分第三方調用問題,在我們的使用中,HTTP服務任務也被我們單獨剝離出來作為一個特殊任務節點。 

接受任務(Receive Task),該任務的名字讓人費解,但它又是最簡單的一種任務,當該任務到達的時候,它不做任何邏輯,而是被動地等待Trigger,它的適用場景往往是一些不明確的阻塞,比如:一個復雜的計算需要等待很多條件,這些條件是需要人為來判斷是否可以執行,而不是直接執行,這個時候,工作人員如果判斷可以繼續了,那么就Trigger一下使其流轉。 

調用活動(Call Activity),調用活動可以理解為函數調用,它會引用另外一個流程使之作為子流程運行,調用活動跟函數調用的功能一樣,使流程模塊化,增加復用的可能性。 

上面大概介紹了一下常用的節點,下面的圖就展示了一個以BPMN2.0為基礎的流程模型,盡量覆蓋到所介紹的所有節點。 

這里是一個生產汽車的流程,從“汽車設計”節點到“批准生產”節點是一個串行的任務,而審批的結果會遇到一個互斥網關,上面講過,互斥網關只需要滿足其中一個條件就會流轉,而這里表達的意義就是審批是否通過。“載入圖紙”是一個服務任務,它是自動執行的,之后會卡在“等待原材料”這個節點,因為這個節點是需要人為去判斷(比如原材料漲價,原材料不足等因素),所以需要在一種自定義的條件下Trigger,而該圖的條件應該為“原材料足夠”,原材料足夠之后,我們會開始並行生產汽車零件。 

需要注意的是,並行網關在圖中是成對出現的,他的作用是開始一系列並行任務和等待並行任務一起完成,拿一個Java中的東西舉例子,就是CountDownLatch,fork-join模型也可以類比。  

說到這里,網關的底層邏輯我作為拓展提一句,沒聽懂也無傷大雅。網關的本質其實是計數器和出口邏輯的混合,它跟其他節點沒什么區別,只是他的推動邏輯需要使他的計數器為0,而計數器的總數為網關入口線段的數量,比如“組裝”節點前面的並行網關,他的計數器就為4,而前面4個節點,每完成一個就會觸發該網關計數器-1。 

當計數器為0的時候,網關會觸發選擇后續流轉的邏輯。 

  • 互斥網關的邏輯為:遍歷所有出口連線,滿足條件則流出並打斷(也就是break掉)。
  • 並行網關的邏輯為:遍歷所有出口連線,無條件為所有連線流出。
  • 包容性網關的邏輯為:遍歷所有出口連線,滿足條件的就流出。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM