• <menu id="gokgi"></menu>
    <nav id="gokgi"><nav id="gokgi"></nav></nav> <menu id="gokgi"><tt id="gokgi"></tt></menu>
    您的位置:首頁 >聚焦 >

    工作流引擎架構設計-當前快播

    2023-01-09 13:00:17    來源:程序員客棧

    最近開發的安全管理平臺新增了很多工單申請流程需求,比如加白申請,開通申請等等。最開始的兩個需求,為了方便,也沒多想,就直接開發了對應的業務代碼。

    但隨著同類需求不斷增多,感覺再這樣寫可要累死人,于是開始了工作流引擎的開發之路。查找了一些資料之后,開發了現階段的工作流引擎,文章后面會有介紹。


    (資料圖片僅供參考)

    雖然現在基本上能滿足日常的需求,但感覺還不夠智能,還有很多的優化空間,所以正好借此機會,詳細了解了一些完善的工作流引擎框架,以及在架構設計上需要注意的點,形成了這篇文章,分享給大家。

    什么是工作流

    先看一下維基百科對于工作流的定義:

    工作流(Workflow),是對工作流程及其各操作步驟之間業務規則的抽象、概括描述。工作流建模,即將工作流程中的工作如何前后組織在一起的邏輯和規則,在計算機中以恰當的模型表達并對其實施計算。

    工作流要解決的主要問題是:為實現某個業務目標,利用計算機在多個參與者之間按某種預定規則自動傳遞文檔、信息或者任務。

    簡單來說,工作流就是對業務的流程化抽象。WFMC(工作流程管理聯盟) 給出了工作流參考模型如下:

    舉一個例子,比如公司辦公的 OA 系統,就存在大量的申請審批流程。而在處理這些流程時,如果每一個流程都對應一套代碼,顯然是不現實的,這樣會造成很大程度上的代碼冗余,而且開發工作量也會驟增。

    這個時候就需要一個業務無關的,高度抽象和封裝的引擎來統一處理。通過這個引擎,可以靈活配置工作流程,并且可以自動化的根據配置進行狀態變更和流程流轉,這就是工作流引擎。

    簡單的工作流

    那么,一個工作流引擎需要支持哪些功能呢?

    這個問題并沒有一個標準答案,需要根據實際的業務場景和需求來分析。在這里,我通過一個工單流程的演進,從簡單到復雜,循序漸進地介紹一下都需要包含哪些基礎功能。

    最簡單流程

    最簡單的一個流程工單,申請人發起流程,每個節點審批人逐個審批,最終流程結束。

    會簽

    在這個過程中,節點分成了兩大類:簡單節點和復雜節點。

    簡單節點處理邏輯不變,依然是處理完之后自動到下一個節點。復雜節點比如說會簽節點,則不同,需要其下的所有子節點都處理完成,才能到下一個節點。

    并行

    同樣屬于復雜節點,其任何一個子節點處理完成后,都可以進入到下一個節點。

    條件判斷

    需要根據不同的表單內容進入不同的分支流程。

    舉一個例子,比如在進行休假申請時,請假一天需要直屬領導審批,如果大于三天則需要部門領導審批。

    動態審批人

    審批節點的審批人需要動態獲取,并且可配置。

    審批人的獲取方式可以分以下幾種:

    固定審批人從申請表單中獲取根據組織架構,動態獲取從配置的角色組或者權限組中獲取撤銷和駁回

    節點狀態變更可以有申請人撤回,審批人同意,審批人駁回。那么在駁回時,可以直接駁回到開始節點,流程結束,也可以到上一個節點。更復雜一些,甚至可以到前面流程的任意一個節點。

    自動化節點

    有一些節點是不需要人工參與的,比如說聯動其他系統自動處理,或者審批節點有時間限制,超時自動失效。

    個性化通知

    節點審批之后,可以配置不同的通知方式來通知相關人。

    以上是我列舉的一些比較常見的需求點,還有像加簽,代理,腳本執行等功能,如果都實現的話,應該會是一個龐大的工作量。當然了,如果目標是做一個商業化產品的話,功能還是需要更豐富一些的。

    但把這些常見需求點都實現的話,應該基本可以滿足大部分的需求了,至少對于我們系統的工單流程來說,目前是可以滿足的。

    工作流引擎對比

    既然這是一個常見的需求,那么需要我們自己來開發嗎?市面上有開源項目可以使用嗎?

    答案是肯定的,目前,市場上比較有名的開源流程引擎有 Osworkflow、Jbpm、Activiti、Flowable、Camunda 等等。其中:Jbpm、Activiti、Flowable、Camunda 四個框架同宗同源,祖先都是 Jbpm4,開發者只要用過其中一個框架,基本上就會用其它三個了。

    Osworkflow

    Osworkflow 是一個輕量化的流程引擎,基于狀態機機制,數據庫表很少。Osworkflow 提供的工作流構成元素有:步驟(step)、條件(conditions)、循環(loops)、分支(spilts)、合并(joins)等,但不支持會簽、跳轉、退回、加簽等這些操作,需要自己擴展開發,有一定難度。

    如果流程比較簡單,Osworkflow 是一個很不錯的選擇。

    JBPM

    JBPM 由 JBoss 公司開發,目前最高版本是 JPBM7,不過從 JBPM5 開始已經跟之前不是同一個產品了,JBPM5 的代碼基礎不是 JBPM4,而是從 Drools Flow 重新開始的?;?Drools Flow 技術在國內市場上用的很少,所有不建議選擇 JBPM5 以后版本。

    JBPM4 誕生的比較早,后來 JBPM4 創建者 Tom Baeyens 離開 JBoss,加入 Alfresco 后很快推出了新的基于 JBPM4 的開源工作流系統 Activiti,另外 JBPM 以 hibernate 作為數據持久化 ORM 也已不是主流技術。

    Activiti

    Activiti 由 Alfresco 軟件開發,目前最高版本 Activiti7。Activiti 的版本比較復雜,有 Activiti5、Activiti6、Activiti7 幾個主流版本,選型時讓人暈頭轉向,有必要先了解一下 Activiti 這幾個版本的發展歷史。

    Activiti5 和 Activiti6 的核心 leader 是 Tijs Rademakers,由于團隊內部分歧,在 2017 年 Tijs Rademakers 離開團隊,創建了后來的 Flowable。Activiti6 以及 Activiti5 代碼已經交接給了 Salaboy 團隊,Activiti6 以及 Activiti5 的代碼官方已經暫停維護了。

    Salaboy 團隊目前在開發 Activiti7 框架,Activiti7 內核使用的還是 Activiti6,并沒有為引擎注入更多的新特性,只是在 Activiti 之外的上層封裝了一些應用。

    Flowable

    Flowable 是一個使用 Java 編寫的輕量級業務流程引擎,使用 Apache V2 license 協議開源。2016 年 10 月,Activiti 工作流引擎的主要開發者離開 Alfresco 公司并在 Activiti 分支基礎上開啟了 Flowable 開源項目?;?Activiti v6 beta4 發布的第一個 Flowable release 版本為 6.0。

    Flowable 項目中包括 BPMN(Business Process Model and Notation)引擎、CMMN(Case Management Model and Notation)引擎、DMN(Decision Model and Notation)引擎、表單引擎(Form Engine)等模塊。

    相對開源版,其商業版的功能會更強大。以 Flowable6.4.1 版本為分水嶺,大力發展其商業版產品,開源版本維護不及時,部分功能已經不再開源版發布,比如表單生成器(表單引擎)、歷史數據同步至其他數據源、ES 等。

    Camunda

    Camunda 基于 Activiti5,所以其保留了 PVM,最新版本 Camunda7.15,保持每年發布兩個小版本的節奏,開發團隊也是從 Activiti 中分裂出來的,發展軌跡與 Flowable 相似,同時也提供了商業版,不過對于一般企業應用,開源版本也足夠了。

    以上就是每個項目的一個大概介紹,接下來主要對比一下 Jbpm、Activiti、Flowable 和 Camunda。只看文字的話可能對它們之間的關系還不是很清楚,所以我畫了一張圖,可以更清晰地體現每個項目的發展軌跡。

    那么,如果想要選擇其中一個項目來使用的話,應該如何選擇呢?我羅列了幾項我比較關注的點,做了一張對比表格,如下:

    Activiti 7Flowable 6CamundaJBPM 7
    流程協議BPMN2.0、XPDL、PDLBPMN2.0、XPDL、XPDLBPMN2.0、XPDL、XPDLBPMN2.0
    開源情況開源商業和開源版商業和開源版開源
    開發基礎JBPM4Activiti 5 & 6Activiti 5版本 5 之后 Drools Flow
    數據庫Oracle、SQL Server、MySQLOracle、SQL Server、MySQL、postgreOracle、SQL Server、MySQL、postgreMySQL,postgre
    架構spring boot 2spring boot 1.5spring boot 2Kie
    運行模式獨立運行和內嵌獨立運行和內嵌獨立運行和內嵌-
    流程設計器AngularJSAngularJSbpmn.js-
    活躍度活躍相對活躍相對活躍-
    表數量引入 25 張表引入 47 張表引入 19 張表-
    jar 包數量引入 10 個 jar引入 37 個 jar引入 15 個 jar-
    Flowable 應用舉例

    如果選擇使用開源項目來開發自己的引擎,或者嵌入到現有的項目中,應該如何使用呢?這里通過 Flowable 來舉例說明。

    使用 Flowable 可以有兩種方式,分別是內嵌和獨立部署方式,現在來分別說明:

    內嵌模式創建 maven 工程

    先建一個普通的 maven 工程,加入 Flowable 引擎的依賴以及 h2 內嵌數據庫的依賴,也可以使用 MySQL 數據庫來做持久化。

    org.flowableflowable-engine6.7.2com.h2databaseh21.4.192

    創建流程引擎實例

    importorg.flowable.engine.ProcessEngine;importorg.flowable.engine.ProcessEngineConfiguration;importorg.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;publicclassHolidayRequest{publicstaticvoidmain(String[]args){ProcessEngineConfigurationcfg=newStandaloneProcessEngineConfiguration().setJdbcUrl("jdbc:h2:mem:flowable;DB_CLOSE_DELAY=-1").setJdbcUsername("sa").setJdbcPassword("").setJdbcDriver("org.h2.Driver").setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);ProcessEngineprocessEngine=cfg.buildProcessEngine();}}

    接下來,我們就可以往這個引擎實例上部署一個流程 xml。比如,我們想建立一個員工請假流程:

    此 xml 是符合 bpmn2.0 規范的一種標準格式,其對應的流程圖如下:

    接下來,我們就把這個文件傳給流程引擎,讓它基于該文件,創建一個工作流。

    RepositoryServicerepositoryService=processEngine.getRepositoryService();Deploymentdeployment=repositoryService.createDeployment().addClasspathResource("holiday-request.bpmn20.xml").deploy();

    創建后,實際就寫到內存數據庫 h2 了,我們還可以把它查出來:

    ProcessDefinitionprocessDefinition=repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();System.out.println("Foundprocessdefinition:"+processDefinition.getName());

    創建工作流實例

    創建工作流實例,需要提供一些輸入參數,比如我們創建的員工請假流程,參數就需要:員工姓名、請假天數、事由等。

    Scannerscanner=newScanner(System.in);System.out.println("Whoareyou?");Stringemployee=scanner.nextLine();System.out.println("Howmanyholidaysdoyouwanttorequest?");IntegernrOfHolidays=Integer.valueOf(scanner.nextLine());System.out.println("Whydoyouneedthem?");Stringdescription=scanner.nextLine();RuntimeServiceruntimeService=processEngine.getRuntimeService();Mapvariables=newHashMap();variables.put("employee",employee);variables.put("nrOfHolidays",nrOfHolidays);variables.put("description",description);

    參數準備好后,就可以傳給工作流了:

    ProcessInstanceprocessInstance=runtimeService.startProcessInstanceByKey("holidayRequest",variables);

    此時,就會根據流程定義里的:

    創建一個任務,任務有個標簽,就是 candidateGroups,這里的 managers,可以猜得出,是給 managers建了個審批任務。

    查詢并審批任務

    基于 manager 查詢任務:

    TaskServicetaskService=processEngine.getTaskService();Listtasks=taskService.createTaskQuery().taskCandidateGroup("managers").list();System.out.println("Youhave"+tasks.size()+"tasks:");for(inti=0;i

    審批任務:

    booleanapproved=scanner.nextLine().toLowerCase().equals("y");variables=newHashMap();variables.put("approved",approved);taskService.complete(task.getId(),variables);

    這里就是把全局變量 approved,設為了 true,然后提交給引擎。引擎就會根據這里的變量是 true還是 false,選擇走不同分支。如下:

    回調用戶代碼

    審批后,就會進入下一個節點:

    這里有個 class,就是需要我們自己實現的:

    最后,流程就走完結束了。

    REST API 模式

    上面介紹的方式是其作為一個 jar,內嵌到我們的程序里。創建引擎實例后,由我們業務程序去驅動引擎的運行。引擎和業務代碼在同一個進程里。

    第二種方式,Flowable 也可以作為一個獨立服務運行,提供 REST API 接口,這樣的話,非 Java 語言開發的系統就也可以使用該引擎了。

    這個只需要我們下載官方的 zip 包,里面有個 rest 的 war 包,可以直接放到 tomcat 里運行。

    部署工作流

    在這種方式下,如果要實現上面舉例的員工請假流程,可以通過調接口來實現:

    啟動工作流:

    其他接口就不一一展示了,可以參考官方文檔。

    通過頁面進行流程建模

    截止到目前,創建工作流程都是通過建立 xml 來實現的,這樣還是非常不方便的。因此,系統也提供了通過頁面可視化的方式來創建流程,使用鼠標拖拽相應組件即可完成。

    但是體驗下來還是比較辛苦的,功能很多,名詞更多,有很多都不知道是什么意思,只能不斷嘗試來理解。

    開源 VS 自研

    既然已經有成熟的開源產品了,還需要自研嗎?這算是一個老生常談的問題了。那到底應該如何選擇呢?其實并不困難,歸根結底就是要符合自身的業務特點,以及實際的需求。

    開源優勢:

    入門門檻低,有很多可以復用的成果。通常而言,功能比較豐富,周邊生態也比較完善,投入產出比比較高。一句話總結,投入少,見效快。

    開源劣勢:

    內核不容易掌控,門檻較高,通常開源的功能和實際業務并不會完全匹配,很多開源產品開箱即用做的不夠好,需要大量調優。一句話總結,入門容易掌控難。

    自研優勢:

    產品核心技術掌控程度高,可以更好的貼著業務需求做,可以定制的更好,基于上述兩點,通常更容易做到良好的性能表現。一句話總結,量身定制。

    自研劣勢:

    投入產出比略低,且對團隊成員的能力曲線要求較高。此外封閉的生態會導致周邊支持缺乏,當需要一些新需求時,往往都需要定制開發。一句話總結,啥事都要靠自己。

    基于以上的分析,再結合我們自身業務,我總結了以下幾點可供參考:

    開源項目均為 Java 技術棧,而我們使用 Python 和 Go 比較多,技術棧不匹配開源項目功能豐富,而我們業務相對簡單,使用起來比較重開源項目并非開箱即用,需要結合業務特點做定制開發,學習成本和維護成本比較高

    綜上所述,我覺得自研更適合我們現階段的產品特點。

    工作流引擎架構設計

    如果選擇自研,架構應該如何設計呢?有哪些比較重要的模塊和需要注意的點呢?下面來詳細說說。

    BPMN

    BPMN 全稱是 Business Process Model And Notation,即業務流程模型和符號。

    可以理解成一種規范,在這個規范里,哪些地方用空心圓,哪些地方用矩形,哪些地方用菱形,都是有明確定義的。

    也就是說,只要是基于這個規范開發的系統,其所創建的流程就都是可以通用的。

    其實,如果只是開發一個內部系統,不遵守這個規范也沒有問題。但要是做一個產品的話,為了通用性更強,最好還是遵守這個規范。

    流程設計器

    對于工作流引擎來說,流程設計器的選型至關重要,它提供了可視化的流程編排能力,決定了用戶體驗的好壞。

    目前主流的流程設計器有 Activiti-Modeler,mxGraph,bpmn-js 等,下面來做一個簡單介紹。

    Activiti-Modeler

    Activiti 開源版本中帶了 Web 版流程設計器,在 Activiti-explorer 項目中有 Activiti-Modeler,優點是集成簡單,開發工作量小,缺點是界面不美觀,用戶體驗差。

    mxGraph

    mxGraph 是一個強大的 JavaScript 流程圖前端庫,可以快速創建交互式圖表和圖表應用程序,國內外著名的 ProcessOne 和 draw.io 都是使用該庫創建的強大的在線流程圖繪制網站。

    由于 mxGraph 是一個開放的 js 繪圖開發框架,我們可以開發出很炫的樣式,或者完全按照項目需求定制。

    官方網站:http://jgraph.github.io/mxgrap

    bpmn-js

    bpmn-js 是 BPMN2.0 渲染工具包和 Web 模型。bpmn-js 正在努力成為 Camunda BPM 的一部分。bpmn-js 使用 Web 建模工具可以很方便的構建 BPMN 圖表,可以把 BPMN 圖表嵌入到你的項目中,容易擴展。

    bpmn-js 是基于原生 js 開發,支持集成到 vue、react 等開源框架中。

    官方網站:https://bpmn.io/

    以上介紹的都屬于是功能強大且完善的框架,除此之外,還有其他基于 Vue 或者 React 開發的可視化編輯工具,大家也可以根據自己的實際需求進行選擇。

    流程引擎

    最后來說說流程引擎,整個系統的核心。引擎設計的好壞決定了整個系統的穩定性,可用性,擴展性等等。

    整體架構如圖所示,主要包括一下幾個部分:

    一、流程設計器主要通過一系列工具創建一個計算機可以處理的工作流程描述,流程建模通常由許多離散的節點步驟組成,需要包含所有關于流程的必要信息,這些信息包括流程的起始和結束條件,節點之間的流轉,要承擔的用戶任務,被調用的應用程序等。

    二、流程引擎主要負責流程實例化、流程控制、節點實例化、節點調度等。在執行過程中,工作流引擎提供流程的相關信息,管理流程的運行,監控流程的運行狀態,并記錄流程運行的歷史數據。

    三、存儲服務提供具體模型及流程流轉產生的信息的存儲空間,工作流系統通常需要支持各種常見的數據庫存儲。

    四、組織模型不屬于工作流系統的建設范圍,但流程設計器在建模的過程中會引用組織模型,如定義任務節點的參與者。還有就是在流程流轉的過程中同樣也需要引用組織模型,如在進行任務指派時,需要從組織模型中確定任務的執行者。

    工作流引擎內部可以使用平臺自身的統一用戶組織架構,也可以適配第三方提供的用戶組織架構。

    五、工作流引擎作為一項基礎支撐服務提供給各業務系統使用,對第三方系統開放標準的 RESTful 服務。

    后記

    下面來說說我現在開發的系統支持到了什么程度,以及未來可能的發展方向。由于畢竟不是一個專門的工單系統,工單申請也只是其中的一個模塊,所以在整體的功能上肯定和完整的工作流引擎有很大差距。

    第一版

    第一版并沒有流程引擎,開發方式簡單粗暴,每增加一個流程,就需要重新開發對應的表和業務代碼。

    這樣做的缺點是非常明顯的:

    每個流程需要單獨開發,工作量大,開發效率低流程功能相近,代碼重復量大,冗余,不利于維護定制化開發,缺少擴展性#第二版

    第二版,也就是目前的版本。

    隨著工單流程逐漸增多,工作量逐漸增大,于是開始對流程進行優化,開發了現階段的工作流引擎。

    在新增一個工單流程時,需要先進行工作流配置,配置其基礎信息,自定義字段,狀態和流轉這些信息。還支持配置自動化節點,可以根據條件由程序自動完成相關操作并審批。

    配置好之后,后端無需開發,由統一的引擎代碼進行處理,包括節點審批流轉,狀態變更等。只需要開發前端的創建和查詢頁面即可,相比于第一版,已經在很大程度上提高了開發效率。

    目前版本需要優化的點:

    缺少可視化流程設計器,無法做到拖拽式設計流程節點之間狀態流轉不夠靈活缺少分布式事物支持,以及異常處理機制下一個版本

    針對以上不足,下一個版本準備主要優化三點,如下:

    需要支持可視化流程設計器,使流程設計更加簡單,靈活根據流程配置自動生成前端頁面,做到新增一種類型的工單,無需開發增加節點自動化能力,異常處理機制,提高系統的穩定性

    以上就是本文的全部內容,如果覺得還不錯的話歡迎點贊,轉發和關注,感謝支持。


    參考文章:

    https://www.cnblogs.com/grey-wolf/p/15963839.htmlhttps://www.cnblogs.com/duck-and-duck/p/14436373.html#!commentshttps://zhuanlan.zhihu.com/p/369761832https://zhuanlan.zhihu.com/p/143739835https://bbs.qolome.com/?p=365https://workflowengine.io/blog/java-workflow-engines-comparison/

    關鍵詞: 流程設計 可以使用

    相關閱讀

    和老少妇做真爽
  • <menu id="gokgi"></menu>
    <nav id="gokgi"><nav id="gokgi"></nav></nav> <menu id="gokgi"><tt id="gokgi"></tt></menu>