跳到主要内容
版本:Next

LMES 流程引擎

摘要

本文档详细介绍了LMES流程引擎的原理、配置方法和应用场景。LMES流程引擎是工作流在产线MES领域的特定应用和深化拓展,专为满足产线复杂的自动化流程管理需求而设计。文档适合系统管理员、开发人员和业务分析师阅读,帮助理解和使用LMES流程引擎。

1、原理

什么是流程引擎?顾名思义,是支持流程编排,流程执行的引擎底座。在低代码平台、办公自动化(OA)、BPM平台、工作流系统均需要流程引擎功能。其解决的问题主要为复杂流程中状态的灵活管理以及可编排性。

LMES 流程引擎是工作流在产线 MES 领域的一种特定应用和深化拓展,它在功能、应用场景和设计目标上与一般的工作流有所不同,更具专业性和针对性,以满足产线复杂的自动化流程管理需求。

以下分别从静态的角度,了解组成LMES流程引擎的要素,以及这些要素如何被组织成流程定义,然后才能从动态的角度,了解流程引擎的工作原理。

1.1、静态模型:流程定义

流程定义由一系列基本的处理活动按照一定的逻辑顺序规则组成,从抽象的角度,流程可以映射成步骤迁移连接组成的有向图,而流转数据则是运行时搭载在流程上的数据和信息。下面分别描述这三个组成要素。

1.1.1、活动(Activity)

在流程引擎中,活动(Activity) 是构成业务流程的基本单元,代表流程中的一个具体操作或步骤。在自动化业务流程引擎中:Activity 翻译为"步骤" 是一个不错的选择。因为这类引擎重点关注系统自动执行的各种操作,"Activity" 通常对应着具体的系统操作步骤,如数据查询、文件传输、指令发送等,"步骤" 能准确传达其在自动化流程中的功能和动作。

步骤往往携带相关的属性,属性包括名称、描述、运行方式、标识等内置属性,还包括不同步骤类型包含的扩展信息,譬如,人工参与步骤,则需要存放人员/角色等相关信息,可扩展性步骤,包含有用户自定义的脚本 Script 属性。步骤是可扩展、可定义、可组合、可重用的。另外,

每个步骤还有迁入/迁出的属性信息。

1.1.1.1、步骤类型

  • 步骤从运行的角度上分,可以分为自动执行人工参与,譬如,"自动执行步骤" 指的是流程在运行过程中,无需人工手动干预,系统按照预先设定的规则和逻辑自动进行的操作环节。"人工参与步骤"是指通过任务通知用户,依靠人工手动启动应用,完成相应的功能(比如审批流程里的,用户选择 通过,拒绝)。
  • 从规模角度上分,可以分为原子步骤和混合步骤,原子步骤是内置不可被分解的操作步骤,譬如:开始步骤、结束步骤,混合步骤是多个原子步骤的组合。
  • 从类型上分,可以有开始步骤、结束步骤、启动子流程步骤等预定义步骤,也可以是通过.NET 脚本定义的可扩展步骤

1.1.1.2、步骤名称

步骤名称:是指该步骤的唯一标识,在整个流程定义文件中必须保持唯一

1.1.1.3、进入/退出

每个步骤在运行时都会触发三个事件,分别是 OnEnter、OnExecute、OnExit 三个事件。

  • 进入模式

    有"手动"和"自动"两个选项,指示进入该步骤的方式。

    如果该步骤的进入模式为"手动" ,则流程运行到该步骤时只会触发该步骤的 OnEnter 事件,然后会等待 用户处理这个步骤时(Flow.RunAsync(ActivityName)) 才会触发 OnExecute 事件;

    如果该步骤的进入模式为"自动" ,则流程运行到该步骤时会触发该步骤的 OnEnterOnExecute 方法。

  • 退出模式

    有"手动"和"自动"两个选项,指示退出该步骤的方式。

    如果该步骤的退出模式为"手动" ,则流程运行到该步骤时只会触发该步骤的 OnExecute 事件,然后会等待用户处理这个步骤时(Flow.RunAsync(ActivityName)) 才会触发 **OnExit ** 事件;

    如果该步骤的退出模式为"自动" ,则流程运行到该步骤时会触发该步骤的 OnExecuteOnExit 方法。

进入模式讨论的是从 OnEnter 到 OnExecute 的执行模式,而退出模式就是从OnExecute 到 OnExit 的模式。

注意: 当步骤是流程的启动步骤时,无论是手动还是自动,OnEnter 方法都不会执行。当步骤是结束步骤时,无论手动还是自动,OnExit 方法都不会行。

骤的进入退出模式

1.1.1.4、迁入/迁出

  • 迁出模式

    含义:描述的是步骤执行完成后,流程将如何继续流转,即该步骤的后置条件或出口条件。它定义了在当前步骤执行完毕后,根据不同的结果或条件,流程会前往哪些后续步骤。共有"SplitAND"和"SplitXOR"两个选项

迁出模式示意图

SplitAND (与拆分):步骤的多个后继步骤,只要后续步骤的迁移条件成立,所有的后续步骤都会被触发。即 平行拆分(Parallel Split)表示流程中从一个线程中的一个点拆分为在多个线程中平行执行的多个活动。a的完成激活了b、c的同时执行。

SplitXOR (异或拆分):步骤的多个后继步骤,后续步骤的迁移条件都成立时,只触发第一个后续步骤。即Exclusive Choice 排他选择,意思就是工作流中的一个点,基于决定或者流程中的数据,流向若干个分支中的一个。 a的完成只能激活b、c的其中一个执行。

  • 迁入模式

    含义:描述的是一个步骤在何种条件下被触发进入,即该步骤的前置条件或入口条件。它定义了流程是如何到达当前步骤的,包括来自哪些其他步骤以及满足什么样的特定条件。共有"JoinAND"和"JoinXOR"两个选项

迁入模式示意图

JoinAND (与合并):步骤的多个前驱步骤,必须所有的前驱步骤都完成,且迁移条件成立,该步骤才会被触发执行。即 同步(Synchronization),表示流程中的多个活动在一个点上汇合成一个线程。要求b、c都被完成,d才会被激活。

JoinXOR (异或合并):步骤的多个前驱步骤,只要有一个前驱步骤完成,且迁移条件成立,该步骤就会被触发执行。即 简单合并(Simple Merge),表示 d或c完成后,d即被激活,不要求b、c都完成。

1.1.2、迁移(Transition)

迁移代表从一个步骤(迁出步骤)切换到另一个步骤(迁入步骤),其中迁出步骤是迁入步骤的前趋步骤,迁入步骤是迁出步骤的后继步骤,迁移与条件结合通过判断迁移上的条件是否成立来完成迁移的过程。通过在迁移上面绑定不同的条件类型。

迁移又分为无条件迁移条件迁移。条件迁移就是指在执行该迁移要满足一定的条件,如设置了某个表达式ok==true,只要该表达式为真就执行这个迁移,否则就不执行这个迁移。无条件迁移就是指一定会执行该迁移,不需要满足任何条件。

1.1.3、条件(Condition)

迁移成立的条件的基类。实现ICondition对条件的定义,迁移是联系环节与环节之间的纽带,每个迁移都必须有方向(单方向)。当环节与环节之间用迁移联系起来后,并不代表执行的时候,环节就能够从源环节跳转到目标环节上。因为每个迁移上还可以绑定迁移条件。只有在迁移条件成立了之后,迁移才能够真正的将两个环节联系起来。

1.1.3.2、属性条件(PropertyCondition)

如果业务数据绑定的是某个对象,这时候就可以使用对象属性条件来直接通过比较该对象的某一属性来判断条件是否成立。当条件的迁移与表单中的某个数据项有关时,就可以用属性条件作为迁移条件。需要特别强调的是:当使用了属性条件时,就要确保这个流程关联的对象里有这样一个属性,否则流程的运转可能会产生错误。

属性条件的 条件表达式掩码: {Parameter}.{Property} {Operator}{PropertyToCompare}

参数名(Parameter):流程上下文标识,即流程数据字典里的一个Key值,如果为空的话就引用ApplicationData参数。

属性名(Property): 如果该Key对应的数据为复杂类型,可通过 参数名.属性名 的方式进一步求值,当 属性名 为空时直接比较 属性名 获取的值。

比较符(Operator): 属性的判断操作。

需要比较的值(PropertyToCompare):如果比较同一个对象的属性可以直接设置属性名,如果需要比较流程参数里面另外一个对象的属性的话,就通过Parameter.Property的形式表达。

**常量值: **需要比较的值如果是常量 则可直接 填写 常量值, 否则使用 需要比较的值, 两者二选一。

属性条件配置界面

1.1.3.3、复合条件(CompositeCondition)

复合条件可以看作为一个条件的容器,通过与和或的关系,组合不同的条件以实现复杂的条件计算。

复合条件示意图

1.2、动态模型:流程实例

1.2.1、流程实例(FlowInstance)

流程定义描述业务流程的执行情况,而流程实例是根据流程定义被真正运行起来的一个实例。流程实例处理包含程的一个定义副本 以及 流转数据

从数学模型上看,流程实例的执行可被标记如下:

用有向图 M = {D,A,T}来表达流程程实例,其中:
D={d1,d2,„,dn}代表流转数据的集合
A={a1,a2,„,an}代表环节的集合
T={t1,t2,„,tn}代表迁移连接的集合, 其中 t1=(aj,ak)为从 aj 到 ak 的迁移, aj,ak∈A
约定:
∀ai,aj∈A,若有 t=(ai,aj)∈T,则 ai 是 aj 的前趋环节,aj 是 ai 的后继环节,t 是 ai 的一条输出迁移,t 是 aj 的一条输入迁移;
若有 A'⊆A,且 A'={a'|(a',a)∈T},则 A'为环节 a 的前趋环节集合;若有 A'⊆A,且A'={a'|(a,a')∈T},则 A'为环节 a 的后继环节集合;
若有 T'⊆T,且 T(a)'={t|t(a,a')∈T},则 T'为环节 a 的输出迁移集合;若有 T'⊆T,且T(a)'={t|t(a',a)∈T},则 T'为环节 a 的输入迁移集合;迁入/迁出集合,支持 XOR 或 AND 运算;
记状态函数
对于∀a∈A,有状态函数 state(a)={-1,0,1},当环节处在未执行状态下,state(a)=-1;当环节正在执行的时候,state(a)=1;当环节执行完毕,state(a)=0;初始状态,∀a∈A,state(a)=-1;
记迁移函数
对于∀t∈T,有迁移函数 tran(t)={-1,0,1}当 tran(t)=1,代表允许发生迁移;当 tran(t)=0,代表迁移不能发生;当 tran(t)=-1,代表了迁移现在还未能确定;对于迁入/迁出集合 T', 支持XOR/AND
存在流转规则如下:
∀a∈A,state(a)≠1, tran(T(a))=1,则 state(a)=1;当 state(a)=1,且执行完毕,state(a)=0;
∀t=(a,a')∈T,当 state(a)从 1 变成 0,若 tran(T(a'))=1,则发生转移,若 tran(T(a'))≠1,则不发生转移,直到下次 state(a)从 1 变成 0 才应用此规则

按照以上的数据描述构成了流程引擎的工作原理,流程引擎处理的流程实例根据其使用的流程定义在与第三方交互下或者系统自动触发下,不断检查满足触发条件的步骤,并且根据执行的情况。如果一个步骤执行完毕,则该步骤对应的状态被设置为 结束,从而触发流程引擎继续流转,直到遇到结束步骤。

流程实例流转

1.2.2、流转数据(DataItems)

流转数据也可以称为 流程上下文 数据,流程上下文是流程引擎在执行流程时,用于存储和管理流程实例相关数据、状态、参数等信息的"虚拟容器",是支撑流程节点交互与逻辑推进的核心要素,按类型分内部数据和外部数据。

内部数据包括:

  • 标准参数数据:如流程标识、流程实例标识等信息
  • 流转运算相关的数据,包括流程运转过程的历史痕迹(日志)、流程当前的状态、各个步骤当前的状态
  • 流转计算过程中的临时数据

外部数据包括:

  • 运行时刻,搭载在流程实例上的数据,可以是文件,也可以是一条业务数据记录
  • 运行时刻,触发该流程的工位配置数据

核心作用:

  • 数据共享:实现不同节点间数据传递
  • 逻辑驱动:作为流程分支、条件判断的依据
  • 状态跟踪:记录流程运行轨迹,支持回溯、监控。例如,通过流程实例ID可查看流程经过的节点与处理记录

流程上下文

1.2.2、生命周期

流程实例的生命周期:指按照流程设定的环节和步骤、遵照流程的规则和规范实际运行的一个具体流程从开始到结束的过程。以下是一般情况下流程实例生命周期的不同阶段:

  1. 创建阶段:当一个具体的业务实例触发流程时,流程实例被创建。此时会为该实例分配唯一的标识符,系统会初始化相关的变量、数据结构等,为流程的后续执行做准备。例如,在工序业务流程中,流程服务启动后,系统就会为所有工位创建其关联的流程对应的流程实例。
  2. 运行阶段:流程实例按照预设的流程路径开始执行,依次经过各个环节和步骤。在这个过程中,可能会涉及到变量操作、数据的处理和传递等操作,每个环节都有相应的处理逻辑和操作。
  3. 等待阶段:在流程执行过程中,可能会因为某些条件不满足而进入等待状态。例如,在进站流程中,需要监听 "进站信号==1",此时流程实例会暂停执行,直到满足继续执行的条件。
  4. 完成阶段:当流程实例经过 结束步骤,这表示流程的一次具体执行过程 已结束,相关的业务处理也已完成。当然也存在一些没有明确结束步骤的流程,这类流程通常具有循环、持续运行或根据特定条件动态变化的特点。没有 结束步骤 的流程,永远都不会自动结束,除非流程抛异常,主动停止,程序退出
  5. 异常处理阶段:在流程执行过程中,如果出现了错误、异常情况或违反了流程规则,就需要进行异常处理。这可能包括回滚操作、记录错误信息,重启流程等,以确保流程的正确性和数据的一致性。异常流程被自动标记为 已结束
  6. 归档阶段:流程实例完成后,相关的执行日志会被归档保存,以便后续查询、审计和分析,流程实例上下文数据暂不做持久化处理。
  7. 销毁阶段: 当流程实例完成其任务并进入结束阶段时,需要将其所占用的内存空间释放出来,以便其他程序或流程实例可以使用这些资源。如果不及时释放内存,可能会导致系统内存泄漏,使可用内存逐渐减少,最终影响系统的性能甚至导致系统崩溃。

流程实例生命周期

2、配置

2.1、流程管理

流程管理界面

  • 每当流程定义出现修改操作时,系统都会自动在数据库内新增一条与之对应的记录,并同步更新当前流程的版本号。采取这种机制,主要目的在于为后续可能的流程回退操作提供有力支撑,确保在业务需求变化或操作失误等情况下,能够便捷、精准地回溯到之前的任意一个有效流程状态。

  • 系统内置的流程现阶段不开放修改权限,原因主要有两个方面。一方面,由于存在不同语种客户群体,流程内容需要进行多语言翻译,统一的内置流程能够确保翻译工作顺利开展,维持内容传达的一致性;另一方面,软件升级时必须同步升级流程定义,一旦用户自行定义流程,将会在升级过程中产生冲突,导致软件无法正常升级,影响使用体验。

  • 同一流程定义的所有流转实例使用同一流程定义(流程模版)。流转过程中,只要将同一份流程模版定义 Clone 出来,即可成为流转实例的流程定义。所有操作都可在内存中进行,性能得到非常好的保证。使用时如果发生流程变化的话,只需要将流程定义模版修改,所有流转中的流程实例都可得到调整而按照重新修订的流程进行流转。

  • 流程管理功能:

    • 新增流程:创建新的流程定义,可以从空白流程开始,或者选择一个模板作为基础。
    • 导入流程:从外部文件(例如 XML 文件)导入流程定义。
    • 导出流程:将流程定义导出到外部文件,以便备份、共享或在其他环境中部署。
    • 克隆流程:复制现有的流程定义,创建一个新的流程,可以基于现有流程进行修改和定制。
    • 查看流程:以只读的方式查看流程图。
    • 删除流程:删除用户自定义流程。
    • 启用/禁用:只有状态为 “启用” 的流程,才能被 流程服务 自动启动,所有流程(包括禁用的)都可以在控制台中手动启动。

2.2.1、新增流程

可使用流程管理功能,新增一个用户定制流程,系统内置流程被设计不可修改,用户可以选择克隆后,在副本上做定制功能。

  • 流程名称:流程的唯一名称,在整个流程管理中不允许重复。

  • 交互类型:包含进出站交互、进站交互、出站交互、其他交互。

    约束:进站交互及出站交互类型的流程,同一个工序只可选一个,其他交互流程可选多个。其中:进出站交互(包含进站交互与出站交互)。

2.2.2、参数配置

在流程管理界面选择一条流程定义数据,右键 “参数配置” 可自定义 流程功能选项和字段配置。

参数配置

以下是“参数配置”包含的内容:

  1. 功能配置
    • 启用/禁用功能:可以启用或禁用流程的某些功能,例如产品状态检测、漏工序检测、重码检测。
    • 配置枚举参数:可以配置某些功能的可选参数,例如条码获取方式、合格判断方式等。

功能配置

  1. 字段配置

    • 显示/隐藏字段:可以控制在 SOP 人工看板中显示或隐藏某些字段,以及渲染的组件类型。
    • 修改字段属性:可以修改字段的属性,例如是否必填、是否只读、默认值等。
    • 自定义字段验证规则:可以定义字段的类型,例如常量、变量、生成条码、解析条码、打印机等。
    • 字段映射:可以将流程中的字段被映射为 变量管理 中的 变量,实现数据同步和集成。

    通过“参数配置”功能,您可以根据实际业务需求,灵活地定制流程的功能和字段,使其更好地适应不同的应用场景。

字段配置

2.2.3、流程设计

流程设计主要有两种方式:

  • 从 XML 文件加载流程定义

    从 XML 加载流程定义 需要熟悉流程引擎的 XML 格式,可以精细控制流程定义的各个方面。

    涉及以下几个步骤:

    1. 编写 XML 文件
      • 确保 XML 文件符合流程引擎所要求的 XML 模式(Schema)。
    2. 导入现有流程
      • 访问流程引擎提供的 Web 界面,找到可视化设计器入口,进入设计器,选择导入现有流程。
      • 流程引擎会对 XML 文件进行验证,确保其符合 XML 模式和流程定义规则。
  • 使用 Web 可视化设计器

    Web 可视化设计器是一种图形化工具,允许您通过拖拽和配置组件来设计流程,而无需手动编写 XML 代码,可通过拖拽方式快速组合控制流活动。修改后可导出XML 流程定义文件或直接调用 WebAPI 接口保存至系统数据库中。

    使用 Web 可视化设计器通常包括以下步骤:

    1. 打开设计器
      • 访问流程引擎提供的 Web 界面,找到可视化设计器入口。
    2. 拖拽和配置组件
      • 从组件面板中拖拽节点、任务、事件、网关等组件到设计画布中。
      • 配置每个组件的属性,例如名称、描述、执行逻辑、输入输出参数等。
    3. 连接组件
      • 使用连接线将各个组件连接起来,定义流程的执行路径。
      • 可以设置条件分支、并行分支等,以实现复杂的业务逻辑。

    流程设计器界面

2.2、流程关联

针对工序流程,流程并不能单独启动运行,而是作为 “流程模板” 可被多个工序关联使用,从而实现,同一业务流程,在运行时,能根据工位配置的不同参数来调整流程行为。流程模板捕捉了业务流程中的通用模式和逻辑,并且通过参数化、配置化、模块化、标准化接口和业务规则的封装,使得流程模板可以灵活地适应不同的场景。 这大大提高了流程的开发效率,降低了维护成本,并增强了系统的灵活性。

流程模板的核心作用:

  1. 流程复用: 通过将通用的业务流程定义为模板,可以在不同的工序或场景中重复使用,避免了重复编写相同流程的代码,大大提高了开发效率。
  2. 流程标准化: 流程模板可以确保在不同的工序或场景中,业务流程的执行方式保持一致,从而实现流程的标准化。
  3. 流程配置化: 流程模板允许通过配置参数来定制流程的行为,而无需修改流程的定义。这使得系统能够适应不同的业务需求,提高了系统的灵活性。
  4. 流程集中管理: 当需要修改流程时,只需要修改流程模板,所有使用该模板的工序或场景都会自动更新。

以下是流程关联的大致步骤:

  1. 工序关联流程: 在工序定义中,可以选择需要关联的多个流程模板。

    关联流程

  2. 工位自动带出流程信息: 在工位配置中,系统能够自动带出该工位关联的流程模板信息。

  3. 自动选择功能配置和字段配置: 根据工位和流程模板的关联关系,自动选择相应的功能配置和字段配置。

参数信号配置

2.3、流程执行

执行流程前,请确认需要执行的流程都已 启用 状态。

跟随启动: 所有 已启用 的流程定义,都会跟随 流程服务 启动/停止 而自动 启动/停止。流程服务 可在 CMS Editor 手动操作启停,CMS Vision无需手动操作,启动软件后会自动启动。注意,当停止 流程服务 时,所有运行中的流程实例 都会被停止执行

流程服务管理界面

手动启动: 手动执行适用于新增流程或修改流程后,需要及时调试,此时如果安装的是CMS Vision是无法 重启 流程服务 的,需要重启整个软件。此时,我们可以借助 流程控制台(适用于未关联工序的流程,已关联工序的流程,使用 **工位控制台 **组件) 来手动操作流程的启、停。

流程控制台界面

对于关联了工序的流程,可以使用 工位控制台 来重置流程。

工位控制台

2.4 流程日志

LMES 流程日志配置文件:CMS Editor\plugins\cms.plugin.messuite\Configs\NLog-Flow.config 可按需配置各类日志生成的存档文件最大个数(默认:不超过50个),以及每个文件的最大大小(默认:20MB)。

2.4.1、变量跟踪日志

存储路径:`logs/flow_logs/{工序名_工位名}/tracelog_xxxx-xx-xx.log`

功能说明:变量跟踪日志专门用于跟踪 LMES对变量的操作。

变量跟踪日志的关键信息:

  • 操作类型:
    • 读变量 : 记录 LMES 何时读取了某个变量的值。
    • 写变量: 记录 LMES 何时修改了某个变量的值,以及修改后的值。
    • 订阅变量: 记录 LMES 何时 接收到了某个变量的变化,以便在变量值发生变化时得到处理。
  • 变量名/值: 明确指出被操作的是哪个变量,以及变量的值。
  • TraceId: 一个唯一的标识符,用于追踪单个请求或事务的完整生命周期。
  • 时间戳: 记录操作发生的时间,用于分析操作的顺序和时间关系。

2.4.2、实例运行日志

存储路径:`logs/flow_logs/{工序名_工位名}/flowlog_xxxx-xx-xx.log`

功能说明:流程实例运行日志,它记录了流程实例从创建到结束的完整生命周期中,每个步骤的处理情况。 这种日志对于流程监控、问题排查和性能分析至关重要。

分析方法:

  • 流程控制台: LMES都提供了自带的监控工具,可以用于查看流程实例的运行日志。
  • 日志管理工具: 使用日志管理工具将流程实例运行日志集中存储和管理,并提供强大的搜索和过滤功能。
  • 自定义分析工具: 根据需要,可以开发自定义的分析工具,用于分析流程实例运行日志,并生成各种报表。

下面我们使用 Notepad++ 软件来具体分析一个流程实例的运行情况。

  • 使用 `{工序名}_{工位名}` 可检索当前工位多次连续进出站的日志信息。

使用工序工位名检索

  • 使用 实例=`{xxxx}` 可检索当前工位某一次的进出站日志信息。

流程实例ID检索

  • 使用 TraceId=`{xxxx}` 可检索变量操作日志,结合 CMS、SIOT 日志,实现跨进程日志的全链路分析。

使用TraceId 全链路检索

3、应用

3.1、流程模式

流程模式是在软件开发和业务流程管理中,为了解决重复出现的特定问题,而总结出的经过验证的可复用解决方案,它提供了一套标准的、通用的方法来设计和实现流程,从而提高效率、降低成本并保证质量。

流程模式

3.1.1、基本模式 (5种)

(1)、顺序模式(Sequence)

最基本的过程模型:按照顺序执行各项活动,前驱活动的完成是后续活动开始的必要条件,每一个 流程引擎系统都直接实现了这种模式,这个模式是流程引擎能运行的一个重要基石。

顺序模式示意图

这个理论模型十分简单,只是一个工作单元完成了,紧接着无条件执行下一个工作单元。

(2)、并行分支模式(Parallel Split)

在流程执行过程中,需要将单进程的某个控制点分成可以并行执行的多进程控制,于是允许任务同时执行或者以任何顺序执行。此一模式,实际就是我们常接触到的 SplitAND 模型。

并行分支模式示意图

值得注意的是这个定义来说一般B、C、D之间是并发的,实现上一般是几个不同的线程/进程。

(3)、同步模式(Synchronization)

AND分支以后,一个最为普遍的合并方式就是 JoinAND 合并。当多个并行任务都完成后才能开始执行下一任务。

同步合并模式示意图

需要注意的细节是"同步"这个问题,很多时候存在现实业务的考虑,即使是同一个动作,也不一定是非要合并不可。

一般情况下,并行分支和合并是组合使用,组合执行模型如下:

并行分支合并组合示意图

(4)、单选模式(Exclusive Choice)

单选模式其实就是 SplitXOR "排它选择" 模式,在流程的某一节点,依据一个结果或流程控制数据, 从多个分支路径中选定一个路径执行。

单选模式示意图

需要注意的是这个"排他"性,只能选择其中一个分支,另外多个分支将不会走下去。

(5)、简单合并模式(Simple Merge)

在流程中某点,需将两个或更多可选分支聚合而不同步;换言之,"合并"在任一入口连接触发时被触发。

简单合并模式示意图

这个模式主要是为了应付前躯只有一个分支的流程,这个模式也是一个很常用的模式。在许多的流程图中,没有显式说明的一般都可以看作是 JoinXOR ,就是任意一个前躯完成,就触发下一个工作单元。一般情况下,单选模式和简单合并模式是组合使用的,组合模式如下:

单选与简单合并组合示意图1

单选与简单合并组合示意图2

3.1.2、高级分支与同步模式

(1)、多选模式(Multiple Choice)

在流程过程的某点,依据判定或流程控制数据,选择一个或多个分支来进行执行。通常意义上来讲就是我们所说的 OR_Split

多选模式示意图

(2)、同步合并模式(Synchronising Join)

流程中某点多条路径聚合成一个线程,若多于一条路径触发,则活动线程需同步;若仅有一条路径触发,则可选分支应再收敛,无需同步。

流程中的多个路径在一个点被汇合成一个单一的进程。如果多于一个的路径到达了,活动线程就需要进行同步。如果只有一个路径到达,那么其它的路径应该异步的重新会聚。

这一个模式是为了应付多选模式(Multiple Choice)或者通常意义所说的 OR-Split 所产生的分支。

同步合并模式示意图

说明:这个分支的合并,需要了解上下文的关系。如果前面只产生了A分支,那么到达 And-Join节点就可以触发后续活动D。如果前面产生的分支A、B、C都被激活触发,并且A、B、C分支是并发的,那么当A、B都已到达同步-JOIN节点,但是C分支还没有到达,那么就需要进行 等待 ,等到C分支也到达本节点后,才能触发执行下一节点D活动。

(3)、多合并模式(Multiple Merge)

多合并模式即多路合并,在流程中某节点,两条或更多分支无同步再收敛。若多于一个分支被激活或多个分支被同时激活,流程需要对每个被激活分支进行响应一次,则需要采用多合并模式。其实多路合并并不是真正意义的合并,而是到达 多路_Join 节点时 继续相同的后续分支

多合并模式示意图

说明:如图所示,B\C\D三个活动,当B先到达" 多路_Join "节点时,则触发E1,C到达时候,触发E2,D到达时候,触发E3,触发完成全部分支后,E触发完成结束。其实每次触发的都是相同的E,但是产生的任务为E1,E2,E3,他们是对每一个流入的分支都进行响应一次功效。当全部触发完成后,流程继续进入E后续的流程活动。

(4)、鉴别器模式(Discriminator)

路径鉴别器是指在流程的某点,激活后续任务之前等待许多流入分支的完成。从它开始之时起,等待所有剩余分支的完成并"忽略"它们。一旦所有的流入分支都被触发,它使自己复位,以便可被再次触发。

鉴别器模式示意图

鉴别器模式只只对And_Split同时执行的情况;此种模式有三种情况:

(1)、B、C同时到达鉴别器Discriminator节点,则执行D

一般这种情况不会发生,因为计算机执行的时候,总是有先后执行顺序的,总有一个为先执行。

(2)、B先到达鉴别器Discriminator节点,那么就不必等待C的执行结果,直接执行D,当C到完成后到达鉴别器Discriminator节点时,流程将自动忽略C的结果,将鉴别器Discriminator恢复原位,继续等待被触发。

(3)、C先到达鉴别器Discriminator节点,那么就不必等待B的执行结果,直接执行D,当B到完成后到达鉴别器Discriminator节点时,流程将自动忽略B的结果,将鉴别器Discriminator恢复原位,继续等待被触发。

(5)、M中的N模式(N-out-of-M Join)

M中选N合并是指流程的某点M 条并行路径聚合到一点,只要其中N条路径完成则激活后续任务,所有其它剩余路径的完成应被忽略。类似于路由鉴别,只要所有流入分支被触发,则该合并使自己复位,以便可被再次触发。M中选N其实就是合并多条路径,进行部分同步,只执行一次后续活动。

M中N模式示意图

说明:上图所示 M 为3,N我们设定为2 ,则,如果B\C 都完成到达N-out-of-M Join节点,则满足N-out-of-M 规则,则不必等待D的执行结果,直接转向执行E;当D完成后到达N-out-of-M Join节点,流程则忽略D的执行结果,将N-out-of-M Join节点复位等待再次被触发。 (LMES 暂不支持)

3.1.3、结构模式

(1)、任意循环模式(Arbitrary Cycles)

在工作流过程的执行过程中,一个或多个任务可被重复执行。

任意循环模式示意图

(2)、隐含终断模式(Implicit Termination)

这个模式叫隐式结束,或者自然结束。就是当所有正在运行结点都没有后继结点,流程就视为结束了。也就是不需要指明结束的结点,只要跑完所有的结点(或者没有找到后继结点),就视为流程结束。

3.1.4、多实例模式

(1)、设计期多实例(Multiple Instances with a Priori Design-Time Knowledge)

流程中的某个任务可能需要创建多个实例,其数目在设计模型时已知。即在某种情形下,一个任务被激活多次,其指定任务在给定情况下实例的个数在设计时已知。这一模式是用于确立多实例的入口方式。入口主要处理的问题就是确定所需要生成的实例个数 N 。而这个 N 在设计流程的时候就确定了。

(2)、运行时前置多实例(Multiple Instances with a Priori Run-Time Knowledge)

一个任务的实例个数是动态的,亦即在设计时未知,而在运行期间所有实例需被执行前的某点可获知其数目。可以将本模式看作一初始化该任务的For循环。在某种情况下,任务可被激活多次,给定任务的实例数在指定情形下是一变量,取决于情况特征或资源的可用性, 但在运行期的某些阶段才已知, 即该任务的实例在运行时候才确定。

入口方式也可以动态确定,这一模式是表示在流程运行的过程中,B 中第一个实例产生以前就确定 N 。当然了,确定这个N 的时机可以是前面 A,也可以是 A 前的工作任务。总之是在第一个实例产生前就确定下来的,也可以视作该模式的应用。

(3)、运行时非前置多实例(Multiple Instances without a Priori Run-Time Knowledge)

实例的数目是动态的,亦即实例数设计时不知,在运行期间,所有这些实例需要被激活前的任何阶段都无法知道。可将本模式看作是任务实例化的**while**循环。

(4)、同步多实例(Multiple Instances without a Priori Run-Time Knowledge)

实例数在设计时未知,任务的所有实例完成后另一任务才能启动(或开始)。

3.1.5、基于状态模式

(1)、延期选择(Deferred Choice)

一个线程激活任务A, 另一线程激活任务 B,而两个任务都在任务列表中,只要一个线程启动, 另一线程应消失(亦即若任务 A 启动,则任务B 应从工作列表中消失)。

流程中的一个节点,有一个或多个分支已经被选择。与XOR拆分相比,并没有明确的选择,但是,选择是取决于环境的。与AND拆分相比,两者中只有一个被执行。这意味着一旦环境启动了其中的一个,另一个就被取消。要注意,选择是被延迟到两个分支中的一个真正开始执行时,也就是说,选择是可以尽可能的推后的。 例子:在收到货物之后,有两种方法可以将其送到。选择取决于相关资源的可用性。因此,选择会被推迟到直到其中一个资源可用为止。

(2)、交叉并行路由(Interleaved Parallel Routing)

一组活动以任意的顺序执行,每个活动都被执行,他们的顺序是在运行时决定的,并且在任意一个时刻都不会有两个活动在执行。

(3)、里程碑(Milestone)

一个活动能否执行取决于一个指定的状态。也就是说,只有在到达一个特定的未过期的里程碑时,活动才被执行。

3.1.6、取消模式

(1)、取消活动(Cancel Activity)

一个可执行的活动、步骤被强制失效了,也就是说,一个正在等待执行的活动、步骤所在线程被移除了。

例子:如果顾客取消了一个请求,那么与之相关的活动也被取消了。

(2)、取消过程(Cancel Instance)

一个流程实例, 被完全取消。

(3)、取消流程(Cancel Flow)

一个流程的所有实例都被取消。

3.1.7、其它模式

结构化循环(Cancel Activity)、递归(Recursion)、临时触发器(Transient Trigger)、持续触发器(Persistent Trigger)、取消范围(Cancel Region)、

多实例的取消(Cancel Multiple Instance Activity)...

3.2、过程推进

3.2.1、业务创建

用户在WEB端流程管理创建流程定义,工序管理配置工序工位,并关联业务流程,配置触发变量等参数信号。

3.2.2、流程启动

第一步完成后,启动业务流程。流程的启动方式分多种,手工启动、自动启动、外部启动等。流程启动过程如下:

  1. 初始化流程
    • 创建流程管理器 FlowManager ,加载流程定义模型(FlowDefinition),初始化流程对象(Processflow ),生成所有步骤的活动实例(ActivityInstance)。
    • 加载工位配置数据(ProcessModel),初始化流程上下文数据(DataItems);
    • 创建流程实例(FlowInstance),状态为:Begin【流程启动】
  2. 状态变更
    • 生成开始步骤的工作任务(FlowItem),将状态变迁为 完成。
    • 将流程实例状态变迁为:Running【流程运行中】

3.2.3、过程执行

流程启动后,LMES流程的设计模式是已经完成了第一开始步骤的所有任务,直接进行第二步骤的执行。此时整个过程开始真正的执行,需要开始分析步骤实例。步骤类型分为以下两种:

  1. 普通步骤

    • 指在工作流过程中,各个活动(人工活动或自动活动)相互之间路径没有分支,只有单一的流向
    • 此种情况下直接读取迁移表的后续步骤的信息

    普通活动示意图

  2. 路由步骤

    • 指在流转过程中,步骤相互之间的路径变迁有多种(大于1)分支
    • 路由步骤分为三种情况:
      • 分裂
      • 汇聚
      • 循环

    路由活动示意图1

    路由活动示意图2

    路由活动示意图3

步骤执行流程:

  1. 条件检查

    • 第一开始步骤执行完成后,根据迁移条件判断是否开始激活运行下一步步骤实例
  2. 实例激活

    • 步骤实例在流程实例创建时已经全部创建完成
    • 此处只需执行激活运行步骤实例
  3. 创建任务

    • 创建工作任务项
  4. 事件触发

    每个步骤在运行时都会触发三个事件,分别是 OnEnter、OnExecute、OnExit 三个事件。如下图所示:(IFlowProcessor为流程处理器,用于二开扩展)

    步骤执行事件示意图

3.2.4、业务结束

结束方式分:Finished(流程结束),流程意外终止(非正常的结束,手动取消或程序异常)

业务流程的结束,系统将自动清除流程实例、步骤实例、工作任务记录,将过程执行情况、任务执行情况的记录状态变更为相应的结束状态。

流程推进

4、常见问题解答(FAQ)

4.1 流程引擎相关问题

4.1.1 什么是 "阻塞步骤"?

阻塞步骤是指在步骤Enter后不会立即完成执行的活动。他们通常会暂停工作流程的进度,直到恢复为止。这种停止的性质创造了"阻塞"一词。常用的阻塞步骤有: "变量监听步骤","定时触发","任务延时" ,"并行流程结束"。

4.1.2 流程实例和流程定义有什么区别?

流程定义是流程的静态模板,描述了流程的结构、步骤和规则;而流程实例是根据流程定义创建的运行时实体,包含了特定执行过程中的数据和状态。一个流程定义可以有多个流程实例。

4.1.3 流程引擎如何处理并发?

流程引擎通过并行分支模式处理并发,允许多个步骤同时执行。每个流程实例有自己的执行上下文,互不干扰,确保数据隔离和一致性。在高并发场景下,流程引擎会使用线程池和队列机制来管理任务执行,避免资源耗尽。

4.2 流程设计相关问题

4.2.1 如何判断流程是否正常运行?

可以通过以下几种方式判断流程是否正常运行:

  1. 查看流程控制台,确认流程实例状态为"Running"
  2. 检查流程日志文件(`logs/flow_logs/{工序名_工位名}/flowlog_xxxx-xx-xx.log`),查看是否有错误信息
  3. 使用工位控制台组件监控流程状态

4.2.2 如何设计高效的流程?

设计高效流程的关键原则:

  • 保持流程简单,避免不必要的复杂性
  • 合理使用并行处理提高效率
  • 明确定义条件分支,避免歧义
  • 使用适当的异常处理机制
  • 定期优化和重构流程定义

4.2.3 如何处理流程中的异常情况?

流程中的异常处理方法包括:设置错误边界事件、使用补偿处理、实现回滚机制、记录详细日志以便分析和调试。

4.3 流程优化相关问题

4.3.1 如何优化流程性能?

优化流程性能的方法:

  • 减少不必要的步骤和条件判断
  • 合理使用并行处理提高吞吐量
  • 优化条件表达式,减少复杂计算
  • 适当使用缓存机制减少重复计算
  • 定期清理历史数据,减轻系统负担

4.3.2 流程引擎的常见性能瓶颈是什么?

流程引擎常见的性能瓶颈包括:复杂条件表达式的计算、大量并发实例的管理、频繁的数据库访问、过多的事件监听器、日志记录过于详细等。

4.4 流程修改与异常处理

4.4.1 流程修改后不生效怎么办?

  1. 确认修改后的流程已设置为"启用"状态
  2. 重启流程服务(在CMS Editor中操作)或使用流程控制台手动重启流程
  3. 检查流程日志,确认是否有加载新流程定义的记录
  4. 如果是关联了工序的流程,可能需要使用工位控制台重置流程

4.4.2 如何处理流程执行过程中的异常?

  1. 查看流程日志,定位异常发生的步骤和原因
  2. 检查流程定义中的条件配置是否正确
  3. 验证流程上下文数据是否符合预期
  4. 使用工位控制台重置流程,或者在流程控制台中重启流程
  5. 如果问题持续存在,可能需要修改流程定义或检查相关系统组件

4.5 流程循环与实例管理

4.5.1 流程结束如何启动新的流程实例?

"结束"步骤中可启用 "新建实例" 属性。

新建实例

4.5.2 有哪些情况会导致 "无限循环",如何避免?

无限循环的常见原因及避免方法:

  1. 逻辑错误(PLC 信号交互):

    • 原因: 流程结束时,PLC 信号未正确复位,导致流程重启时信号状态异常,条件持续成立,陷入无限循环。
    • 避免方法:
      • 在 PLC 程序中添加信号复位逻辑。
      • 在监控系统中添加复位功能,流程重启前检查并复位信号。
      • 在流程关键节点进行信号状态检查和验证。
  2. 未处理的异常情况:

    • 原因: 程序运行中出现异常(如除数为零),但没有适当的异常处理机制,导致流程不断重复执行错误操作。
    • 避免方法:
      • 延迟重启流程实例,等待系统环境恢复正常。
      • 使用异常捕获语句,在捕获到异常时进行预先设定的处理,保证系统稳定性。

总而言之,避免无限循环的关键在于确保流程条件能够终止,以及妥善处理可能出现的异常情况