蓝凌EKP18产品:整体架构

一、四层架构总览

EKP 流程引擎采用经典的四层分层架构,从外到内依次是:

复制代码
┌─────────────────────────────────────────────────────────┐
│                    应用层 (Application)                   │
│                                                         │
│   业务模块调用入口:发起流程、审批、驳回、转办、加签...       │
│   提供给前端/第三方系统的 REST API / Java API              │
│                                                         │
│   对应模块: sys-lbpmweb, sys-lbpmext, sys-lbpmdocking    │
├─────────────────────────────────────────────────────────┤
│                    引擎层 (Engine)                        │
│                                                         │
│   ┌─────────────────────────────────────────────────┐   │
│   │              上层:业务服务层                       │   │
│   │   流程模板管理、模拟仿真、变更日志、事件监听...       │   │
│   │   对应模块: sys-lbpmservice                       │   │
│   └─────────────────────────────────────────────────┘   │
│   ┌─────────────────────────────────────────────────┐   │
│   │              中层:引擎调度层                       │   │
│   │   操作行为调度、执行参数管理、节点属性解析...        │   │
│   │   包路径: engine/manager, engine/operation         │   │
│   └─────────────────────────────────────────────────┘   │
│   ┌─────────────────────────────────────────────────┐   │
│   │              底层:PVM 虚拟机                      │   │
│   │   执行路径管理、原子操作调度、事件分发、状态机       │   │
│   │   包路径: pvm/ (执行、操作、事件、上下文)           │   │
│   └─────────────────────────────────────────────────┘   │
│                                                         │
│   对应模块: sys-lbpm                                    │
├─────────────────────────────────────────────────────────┤
│                    持久层 (Persistence)                   │
│                                                         │
│   数据访问对象 (DAO)、ORM映射、数据库表结构               │
│   对应子包: engine/persistence                          │
│   核心表: 流程实例表、执行路径表、工作项表、流程定义表...   │
├─────────────────────────────────────────────────────────┤
│                    基础层 (Infrastructure)                │
│                                                         │
│   Spring 容器、事务管理、权限框架、缓存、消息队列...        │
│   对应模块: CORE, com, sys-cache, sys-right 等           │
└─────────────────────────────────────────────────────────┘

关键认识

这不是简单的四层堆叠,而是两套正交系统的组合:

  • 纵向:按调用层次划分(谁调谁)

  • 横向:按功能领域划分(管什么)

同一层里,不同模块各管一块,互不干扰;跨层时,通过接口契约通信,上层依赖下层,下层绝不反向调用。


二、引擎层深度拆解

引擎层是整套系统的核心,从下到上又可以细分为三个子层:

2.1 底层:PVM 流程虚拟机

PVM 是流程引擎的"CPU",职责纯粹而关键------只管"怎么走",不管"走什么"。

它关心的内容:

关心 不关心
当前执行路径在哪个节点 这个节点是审批还是发邮件
原子操作的排队和执行顺序 每个原子操作内部的业务细节
事件如何发布和分发 事件监听器做了什么业务处理
执行路径的父子关系和状态转换 这些数据怎么存到数据库

PVM 的六大子包各司其职:

  • execution(执行路径):流程的"当前位置指针",树形结构,6 种状态

  • operation(原子操作):最小执行单元,双队列调度

  • event(事件):流程生命周期事件定义(启动、进入节点、离开节点、结束...)

  • builder(定义模型):流程定义的抽象表示(节点、路由、条件)

  • context(上下文):执行环境、参数传递、变量作用域

  • service(服务接口):PVM 与引擎层的解耦契约(EngineWire、EngineProvider)

2.2 中层:引擎调度层

这一层是 PVM 虚拟机和具体业务之间的"中间件"。它的核心任务是:

把 PVM 发出的"指令"翻译成具体的业务动作。

关键模块:

Manager(管理器)

Manager 层掌握流程运行的全局状态和环境:

  • ProcessServiceManager:流程服务的总入口,协调各个子系统

  • ExecutionParameters:包装流程执行时需要的全部参数(实例ID、操作类型、临时变量...)

  • ProcessParameters:流程实例级别的参数上下文,贯通整个执行周期

  • ResourceCache:流程定义、节点配置的缓存,避免每次执行都重新解析

Operation(操作行为)

Operation 层定义了人工操作的抽象行为模板:

  • AbstractOperationBehaviour:所有操作行为的基类,定义了"接收信号→执行业务→决定路由"的标准流程

  • AbstractManualOperationBehaviour:人工审批操作(同意/驳回/转办等)的通用逻辑

  • AbstractAdditionOperationBehaviour:加签操作的通用逻辑

这些抽象类定义了"模板方法"------子类只需填充具体的业务逻辑,调度流程由父类统一控制。

Node(节点类型)

Engine 内置了四种标准节点,每种都有对应的 Behaviour(行为类):

节点类型 作用 对应的 Behaviour
StartNode 流程起点,生成发起人待办 StartNodeBehaviour
EndNode 流程终点,触发结束事件 EndNodeBehaviour
SplitNode 并行分支网关,分裂执行路径 SplitNodeBehaviour
JoinNode 聚合分支网关,等待分支汇合 JoinNodeBehaviour

2.3 上层:业务服务层

这一层最接近应用层,处理流程引擎的"业务外围"功能。它不属于引擎核心但又是流程系统不可或缺的部分。

核心模块 sys-lbpmservice 包含:

  • 流程模板管理:流程定义的发布、版本管理、变更日志

  • 模拟仿真:在不产生真实数据的前提下预览流程走向

  • 事件监听处理:审批通过后发通知、更新关联数据、触发下游流程

  • 流程图导入导出:可视化流程图与流程定义 XML 的互转

  • 定时任务:超时提醒、自动催办、过期处理

  • 外部系统对接:钉钉、飞书、第三方 OA 的消息推送


三、模块间的交互流程

接下来,我们用"一次完整的审批流转"串联起各层的协作关系:

3.1 从宏观到微观的三级视角

第一级:系统间视角

复制代码
用户浏览器 → 前端应用 → REST API → 流程引擎 → 数据库

这是最粗粒度的视图,每一步只看到调用方向。

第二级:模块级视角

复制代码
浏览器
   │ POST /api/workitem/complete
   ▼
sys-lbpmweb (REST Controller)
   │ 调用 service 接口
   ▼
sys-lbpmservice (业务服务)
   │ 组装参数, 执行操作行为
   ▼
sys-lbpm (引擎核心)
   │ PVM 驱动执行路径流转
   ▼
engine/persistence (持久层)
   │ 写入工作项状态、执行路径状态
   ▼
数据库

第三级:引擎内部视角(这就是第六课追踪过的路径)

复制代码
ProcessServiceManager 接收请求
   │
   ▼
创建 ExecutionContext(上下文)
   │
   ▼
ExecutionWraper.signal() 激活执行路径
   │
   ▼
Signal 原子操作 → 节点 Behaviour.signal()
   │
   ▼
TransitionEndTask 结束当前任务
   │
   ▼
TransitionStartTask 启动下一节点
   │
   ▼
ExecuteTask 执行节点行为

3.2 关键转折点:人工节点 vs 自动节点

整个流转过程中有一个关键分叉:

复制代码
ExecuteTask
   │
   ├── [人工节点]
   │     创建待办工作项
   │     设置状态 = WAITING
   │     通知相关人员
   │     ← 执行暂停,等待外部信号
   │
   └── [自动节点]
         执行业务逻辑(计算、发通知、调接口...)
         自动完成
         继续向前流转
         ← 不停顿,直接进入下一节点

这就是为什么流程引擎在架构上天然分成"同步执行"和"异步等待"两部分。 自动节点在引擎内部一次性跑完;人工节点则需要执行路径"停下来",等待外部用户的操作信号。


四、六大关键抽象

架构的好坏,关键看抽象设计。EKP 流程引擎定义了六组核心抽象,每一组都精准地解耦了一个维度的变化:

4.1 EngineWire ------ 执行路径的"持久化抽象"

PVM 层不操作数据库------它只管内存中的执行路径对象。所有"创建执行路径""查找执行路径""删除执行路径"的操作,都通过 EngineWire 接口委托给引擎层。

这意味着什么? 如果未来要把执行路径从关系数据库迁移到 Redis 或 MongoDB,只需换一个 EngineWire 实现,PVM 层一行代码不用改。

4.2 ActivityBehaviour ------ 节点行为的"可插拔抽象"

每个节点类型对应一个 ActivityBehaviour 实现。引擎调度层只和这个接口打交道,不关心具体节点类型。

这意味着什么? 要扩展自定义节点(比如"外部接口调用节点"),只需实现 ActivityBehaviour 接口,然后注册到系统中即可------不用修改引擎核心的任何代码。

4.3 AtomicOperation ------ 执行步骤的"最小单元抽象"

"启动任务""执行任务""结束任务""移动父任务"------每一种流转动作都封装为独立的原子操作。它们通过名称互相引用,通过队列统一调度。

这意味着什么? 要新增一种流转动作(比如"跳过当前节点"),只需新增一个 AtomicOperation 实现,然后在合适的事件监听器中触发它。

4.4 JoinStrategy ------ 聚合策略的"策略抽象"

并行分支汇合时,"任意一人通过"还是"全部通过"?不同场景需要不同的聚合策略。JoinStrategy 接口将策略定义与引擎核心分离:

  • AnyoneJoinStrategy:有一人通过即完成聚合

  • AndJoinStrategy:所有人通过才算完成聚合

这意味着什么? 如果要支持"超过半数即通过"的投票模式,只需新增一个 VoteJoinStrategy 实现,通过配置即可切换,无需修改分支聚合的核心逻辑。

4.5 ProcessServiceManager ------ 服务调用的"门面抽象"

这是引擎对外的总入口。无论是 Web 层的 REST 接口,还是第三方系统的远程调用,最终都通过 ProcessServiceManager 进入引擎内部。

它就像一个前台------统一接待,分发给后台各个"职能部门"处理。

4.6 ExecutionContext ------ 一次执行的"快照抽象"

每次操作都会创建一个 ExecutionContext,它封装了当前执行所需的一切:

  • 当前执行路径在哪

  • 关联的流程定义是什么

  • 流程参数有哪些

  • 引擎的服务提供器是谁

这相当于把"执行现场"打了个包------后续的所有原子操作、事件监听都基于这个上下文展开,不需要反复查询数据库。


五、架构中的设计模式

EKP 流程引擎的设计中,几个经典模式贯穿始终:

5.1 模板方法模式

最典型的应用在操作行为层:

复制代码
AbstractOperationBehaviour(模板)
   │
   ├── signal()         ← 模板方法,定义标准流程
   │   ├── preSignal()  ← 钩子,子类可选覆盖
   │   ├── doExecute()  ← 抽象方法,子类必须实现
   │   └── postSignal() ← 钩子,子类可选覆盖
   │
   └── 子类实现: AgreeOperationBehaviour, RejectOperationBehaviour...

价值:确保所有操作行为遵循统一的调度流程,子类开发者只需关心业务逻辑,不用管调度机制。

5.2 策略模式

JoinStrategy 是典型策略模式。聚合节点的核心逻辑不依赖具体策略,运行时动态注入。

价值:新增聚合方式不影响聚合节点的核心实现,符合"对扩展开放,对修改关闭"的原则。

5.3 观察者模式(事件驱动)

PVM 的整个流转过程基于事件驱动。节点进入、节点离开、任务激活、任务结束------每个关键时刻都发布事件,监听器们各取所需地响应。

价值:新需求(比如"审批通过后自动发企业微信通知")只需新增一个事件监听器,核心流转逻辑不受影响。

5.4 门面模式

ProcessServiceManager 作为引擎的统一入口,屏蔽了内部复杂度。外部调用者不需要知道 PVM、原子操作、执行路径这些概念,只需调用 startProcess()completeWorkitem() 等语义明确的方法。

价值:降低使用门槛,同时保护内部实现细节,后续重构不影响外部调用方。


六、架构的核心原则

回顾整个架构设计,可以提炼出五条原则,它们共同构成了这套系统的"设计哲学":

原则一:关注点分离

引擎核心只管流转,不管业务。

PVM 不知道什么叫"审批通过",它只知道"当前节点结束了,沿着路由走到下一个节点"。审批逻辑是挂在节点上的 Behaviour 去执行的。

原则二:依赖倒置

上层依赖接口,下层实现接口。

引擎层定义 ActivityBehaviour 接口,业务层提供实现。不是引擎调用业务,而是引擎调用接口,接口背后是什么它不关心。

原则三:小步快走

复杂流转 = 多个原子操作的链式组合。

一次"审批通过并流转到下一节点"看似一步操作,实际分解为:结束当前任务 → 找到下一路由 → 启动下一节点 → 执行节点行为。每步都是独立、可跟踪、可回滚的小操作。

原则四:显式状态

所有状态必须显式表达,不允许"隐含状态"。

执行路径的六种状态(ACTIVE/WAITING/SUSPENDED/ENDING/ENDED/CONCURRENT)互斥且完备。不存在"既是等待又是激活"的模糊情况。这种严格的状态机设计是流程可靠性的基石。

原则五:可观测性

每个关键动作都留下痕迹。

事件机制不仅是扩展机制,也是观测手段。流程启动、节点进入、任务创建、操作完成------都有对应的事件。监控系统可以监听这些事件来构建执行轨迹、性能仪表盘和异常告警。


相关推荐
恒拓高科WorkPlus1 小时前
BeeWorks Meet私有化视频会议:内网会议、组织架构联动与会议安全
安全·架构
青山木2 小时前
Hot 100 --- 岛屿数量
java·数据结构·算法·leetcode·深度优先·广度优先
程序员-珍2 小时前
报错下载android sdk失败
android·java
adinnet20262 小时前
深度拆解企业级 Agent 架构:LangGraph + 知识图谱 + 向量检索的协同设计
人工智能·架构·知识图谱
糖果店的幽灵2 小时前
langgraph分支之 - 动态分支(Dynamic Branch)
java·前端·javascript·人工智能·langgraph
吃饱了得干活2 小时前
亿级订单表分库分表设计,从0到1全流程
java·数据库·面试
listening7772 小时前
HarmonyOS 6.1 混沌工程实战:从“故障免疫”到“韧性架构”
华为·架构·harmonyos
晚风吹长发3 小时前
Docker使用——Docker容器及相关命令
linux·运维·服务器·docker·容器·架构
郝学胜-神的一滴3 小时前
[简化版 GAMES 104] 现代游戏引擎 02:拆解现代游戏引擎5+1层级架构,吃透引擎底层核心逻辑
c++·unity·架构·游戏引擎·图形渲染·unreal engine·系统设计
唐青枫3 小时前
Java Spring Security 实战详解:从登录认证到 JWT 权限控制
java