Flowable

以下是关于 Flowable工作流引擎使用与配置 的详细指南,涵盖核心概念、环境搭建、流程设计及配置要点:

一、Flowable 核心概念

  1. 流程引擎
    负责解析 BPMN 2.0 流程定义,管理流程实例、任务、历史数据等。
  2. BPMN 2.0
    标准流程建模语言,支持 UserTask(用户任务)、ServiceTask(服务任务)、ExclusiveGateway(排他网关)等元素。
  3. 流程实例
    每次启动流程时创建的运行时实例。
  4. 任务(Task)
    流程中需要人工或自动处理的操作节点。

二、环境配置(Spring Boot 集成)

1. 添加 Maven 依赖
<dependency>
    <groupId>org.flowable</groupId>
    <artifactId>flowable-spring-boot-starter</artifactId>
    <version>6.7.2</version>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId> <!-- 示例使用 H2 内存数据库 -->
</dependency>
2. 配置文件 application.yml
flowable:
  database-schema-update: true # 自动更新数据库表结构
  async-executor-activate: true # 启用异步任务执行器
  history-level: audit # 历史记录级别(audit 记录基础审计信息)

三、流程设计与部署

1. 创建 BPMN 2.0 流程定义(XML)
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL">
  <process id="leave_approval" name="请假审批流程">
    <startEvent id="start" />
    <userTask id="apply_leave" name="提交请假申请" />
    <sequenceFlow sourceRef="start" targetRef="apply_leave" />
    
    <userTask id="manager_approve" name="经理审批" />
    <sequenceFlow sourceRef="apply_leave" targetRef="manager_approve" />
    
    <exclusiveGateway id="decision" />
    <sequenceFlow sourceRef="manager_approve" targetRef="decision" />
    
    <sequenceFlow id="approved" sourceRef="decision" targetRef="end">
      <conditionExpression xsi:type="tFormalExpression">${approved}</conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="rejected" sourceRef="decision" targetRef="apply_leave" />
    
    <endEvent id="end" />
  </process>
</definitions>
2. 部署流程到引擎
@Autowired
private RepositoryService repositoryService;

public void deployProcess() {
    repositoryService.createDeployment()
        .addClasspathResource("processes/leave_approval.bpmn20.xml")
        .deploy();
}

四、流程运行与任务处理

1. 启动流程实例
@Autowired
private RuntimeService runtimeService;

public void startProcess() {
    Map<String, Object> variables = new HashMap<>();
    variables.put("applicant", "张三");
    runtimeService.startProcessInstanceByKey("leave_approval", variables);
}
2. 查询并完成任务
@Autowired
private TaskService taskService;

public void completeTask(String taskId) {
    Map<String, Object> variables = new HashMap<>();
    variables.put("approved", true); // 审批通过
    taskService.complete(taskId, variables);
}

五、关键配置项说明

  1. 数据库配置
    支持 MySQL、PostgreSQL 等,需配置数据源:

    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/flowable
        username: root
        password: 123456
    
  2. 历史日志级别

    • none:不记录历史
    • activity:记录节点事件
    • audit(推荐):记录任务、变量变更
    • full:完整审计日志(性能开销大)
  3. 异步执行器
    用于处理定时任务、异步任务,需在配置中激活:

    flowable:
      async-executor-activate: true
    

六、高级功能

  1. 服务任务(自动逻辑)
    实现 JavaDelegate 接口处理业务逻辑:

    public class SendEmailTask implements JavaDelegate {
        @Override
        public void execute(DelegateExecution execution) {
            System.out.println("发送审批通知邮件...");
        }
    }
    
  2. 监听器
    捕获流程事件(如任务创建、流程结束):

    public class TaskListenerImpl implements TaskListener {
        @Override
        public void notify(DelegateTask task) {
            task.setAssignee("经理"); // 自动分配任务
        }
    }
    

七、监控与管理

  • Flowable UI:通过官方 UI 控制台(需单独部署)可视化监控流程、任务、历史数据。
  • REST API:内置 REST 接口,支持第三方系统集成流程操作。

提示:生产环境建议启用数据库连接池(如 HikariCP)并调整线程池参数。复杂流程建议使用 Flowable Modeler 进行图形化设计。

思维导图

在这里插入图片描述


Flowable 工作流引擎技术原理详解

一、核心工作原理

Flowable 基于 BPMN 2.0 规范实现,采用事件驱动模型处理流程实例。其核心运行机制如下:

  1. 流程解析:将 BPMN XML 解析为内存中的对象模型ProcessDefinition
  2. 状态机驱动:每个流程节点实现为状态机,通过事件(ACTIVITY_START/END)触发状态转换
  3. 异步执行:通过JobExecutor线程池处理异步任务,避免阻塞主线程
  4. 持久化机制:使用ACID事务将运行时状态持久化到数据库,支持故障恢复
二、核心算法与数据结构
  1. 流程执行算法

    启动流程
    是否存在异步任务
    写入ACT_RU_JOB表
    同步执行任务
    JobExecutor轮询
    锁定任务并执行
  2. 关键数据结构

    数据结构作用实现类
    流程定义存储解析后的BPMN元素ProcessDefinitionEntity
    执行实例树维护父子执行路径ExecutionEntity
    任务队列管理待处理任务TaskEntity
    历史日志记录流程执行轨迹HistoricActivityInstance
  3. 并发控制算法
    采用 乐观锁(Optimistic Locking) 机制:

    // 更新实体时自动检查版本号
    public void updateExecution(ExecutionEntity execution) {
        int version = execution.getVersion();
        execution.setVersion(version + 1);
        // SQL: UPDATE ACT_RU_EXECUTION SET REV_ = ? WHERE ID_ = ? AND REV_ = ?
    }
    

    冲突时抛出OptimisticLockingException触发重试

三、核心组件架构
持久层
数据库
MyBatis
RepositoryService
管理流程定义
RuntimeService
启动流程实例
TaskService
处理用户任务
HistoryService
查询历史数据
ManagementService
管理引擎配置
四、优缺点分析

优点

  1. 轻量级设计(核心JAR < 10MB)
  2. 高性能处理(单节点支持 1000+ TPS)
  3. 完善的Spring Boot集成
  4. 支持分布式部署

缺点

  1. 复杂流程调试困难
  2. 历史数据膨胀问题
  3. 高并发下数据库压力大
  4. 学习曲线陡峭
五、Java 代码示例
// 1. 流程部署(带中文注释)
public void deployProcess(Resource bpmnResource) {
    Deployment deployment = repositoryService.createDeployment()
        .addInputStream("leaveProcess.bpmn", bpmnResource.getInputStream())
        .name("请假流程")
        .deploy(); // 触发BPMN解析和持久化
    
    System.out.println("部署ID: " + deployment.getId());
}

// 2. 启动流程实例
public void startProcess(String processKey) {
    Map<String, Object> variables = new HashMap<>();
    variables.put("days", 3); // 流程变量
    
    ProcessInstance instance = runtimeService.startProcessInstanceByKey(
        processKey, 
        variables // 变量自动序列化到数据库
    );
    
    System.out.println("实例ID: " + instance.getId());
}

// 3. 任务处理(含服务任务)
public class ApprovalService implements JavaDelegate {
    @Override
    public void execute(DelegateExecution execution) {
        // 从执行上下文中获取流程变量
        Integer days = (Integer) execution.getVariable("days");
        boolean approved = days <= 5; // 审批逻辑
        
        execution.setVariable("approved", approved); // 设置决策变量
        System.out.println("审批结果: " + approved);
    }
}

// 4. 历史数据查询
public void queryHistory(String processInstanceId) {
    List<HistoricActivityInstance> activities = historyService
        .createHistoricActivityInstanceQuery()
        .processInstanceId(processInstanceId)
        .orderByHistoricActivityInstanceStartTime().asc()
        .list();
    
    activities.forEach(act -> 
        System.out.println(act.getActivityName() + " : " + act.getDurationInMillis() + "ms")
    );
}
六、性能优化策略
  1. 数据库优化
    CREATE INDEX idx_act_ru_exec ON ACT_RU_EXECUTION(PROC_INST_ID_); 
    -- 加速流程实例查询
    
  2. 缓存配置
    flowable:
      process-definition-cache: 500 # 增加流程定义缓存
      process-model-cache: 100      # 模型解析缓存
    
  3. 异步调优
    // 自定义异步执行器
    AsyncExecutor customExecutor = new DefaultAsyncJobExecutor();
    customExecutor.setCorePoolSize(10);  // 核心线程数
    customExecutor.setMaxPoolSize(50);   // 最大线程数
    processEngineConfiguration.setAsyncExecutor(customExecutor);
    

提示:生产环境建议结合 Redis 缓存流程定义,复杂网关逻辑优先使用 DMN 决策表实现。调试时启用 flowable.process-engine-history: full 获取完整日志(需评估性能影响)。

思维导图

在这里插入图片描述


Flowable 技术深度解析与最佳实践

一、动态任务分配实现

通过 委托表达式运行时 API 实现动态分配:

// 1. 委托表达式(BPMN配置)  
public class DynamicAssignHandler implements TaskListener {  
    @Override  
    public void notify(DelegateTask task) {  
        String assignee = calculateByBusinessRule(task.getVariables());  
        task.setAssignee(assignee); // 动态设置负责人  
    }  
}  

// 2. 运行时改派  
taskService.setAssignee(taskId, "newAssignee");  

扩展场景

  • 会签加签:通过 addUserIdentityLink(taskId, userId, "candidate") 动态添加参与者
  • 条件分配:结合 EL 表达式 ${assignee = userService.resolveOwner(task)}
二、Flowable vs Camunda vs Activiti 核心区别
维度FlowableCamundaActiviti
架构特性轻量级嵌入引擎企业级独立引擎 + Zeebe基础流程引擎
动态能力原生支持动态流程修改需插件扩展有限支持
性能指标5,000 实例/秒15,000 实例/秒3,000 实例/秒
中国特色内置加签/转签/会签需定制开发需定制开发
高可用手动配置集群内置 Raft 协议自动选主无原生支持

选型建议

  • 复杂企业级流程 → Camunda
  • 动态审批场景 → Flowable
  • 简单 BPMN 管理 → Activiti
三、高并发性能优化策略
  1. 异步执行调优
AsyncExecutor executor = new DefaultAsyncJobExecutor();  
executor.setCorePoolSize(Runtime.getRuntime().availableProcessors() * 2);  
executor.setMaxAsyncJobsDuePerAcquisition(500); // 单次获取任务数  
  1. 数据库优化
-- 关键索引  
CREATE INDEX idx_act_ru_execution_procdef ON ACT_RU_EXECUTION(PROC_DEF_ID_);  
ALTER TABLE ACT_RU_JOB ADD INDEX idx_job_duedate(DUEDATE_);  
  1. 缓存配置
flowable:  
  process-definition-cache: 1000  
  knowledge-base-cache-max: 500  
  async-executor-lock-wait-time: 120s  # 减少锁竞争  
  1. 水平扩展
负载均衡
Flowable实例
Flowable实例
共享数据库集群
四、多实例任务(会签)设计
<userTask id="multiInstanceTask">  
  <multiInstanceLoopCharacteristics  
    isSequential="false"  
    flowable:collection="${approverList}"  
    flowable:elementVariable="approver">  
    <completionCondition>  
      ${nrOfCompletedInstances/nrOfInstances >= 0.6}  <!-- 60%通过即完成 -->  
    </completionCondition>  
  </multiInstanceLoopCharacteristics>  
</userTask>  

关键参数

  • isSequential:并行(false)/串行(true)
  • collection:动态参与者列表(支持 EL 表达式)
  • completionCondition:完成条件(支持数学表达式如 $ {nrOfRejectedInstances<2}
五、历史数据清理策略

分级清理方案

数据类型保留策略清理方式
核心业务数据3年归档至数据仓库
普通流程实例180天定时删除
运行时日志30天自动清理

技术实现

historyService.createHistoricProcessInstanceQuery()  
  .finishedBefore(LocalDate.now().minusDays(180))  
  .deleteWithRelatedData(); // 级联删除  
六、高可用集群部署

架构要点

  1. 共享数据库:MySQL Cluster 或 PostgreSQL HA
  2. 集群配置
flowable.async.executor.cluster.enabled=true  
flowable.async.executor.lock.retry.wait=5s  
  1. 故障转移:通过 Redis 实现分布式锁管理

部署拓扑

Client
Nginx
App+Flowable
App+Flowable
Redis Sentinel
MySQL HA
七、流程版本控制机制
  1. 自动版本升级
repositoryService.createDeployment()  
  .addString("process.bpmn", newModelXML)  
  .deploy(); // KEY相同则版本+1  
  1. 运行中实例迁移
runtimeService.createProcessInstanceMigrationBuilder()  
  .migrateToProcessDefinition("newVersionId")  
  .addActivityMapping("oldTask", "newTask")  
  .execute();  
八、历史数据自动清理最佳实践
# application.yml  
flowable:  
  history-cleaning:  
    enabled: true  
    cycle: 0 0 2 * * ?  # 每天2点执行  
    time-window: P180D   # 保留180天  
    batch-size: 2000     # 分批删除  

分区表优化

-- 按年分区的历史表  
CREATE TABLE act_hi_taskinst_2024 PARTITION OF act_hi_taskinst  
  FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');  
九、动态加签/减签实现

加签逻辑

// 1. 动态添加参与者  
taskService.addUserIdentityLink(taskId, "newUser", "candidate");  

// 2. 修改多实例集合  
List<String> approvers = (List)runtimeService.getVariable(execId, "approverList");  
approvers.add("newUser");  
runtimeService.setVariable(execId, "approverList", approvers);  

减签逻辑

// 1. 移除未处理的任务  
taskService.deleteTask(taskId, "减签操作");  

// 2. 更新完成条件  
runtimeService.setVariable(execId, "requiredApprovals", 3);  
十、微服务集成方案
  1. 轻量级嵌入
<dependency>  
  <groupId>org.flowable</groupId>  
  <artifactId>flowable-spring-boot-starter</artifactId>  
  <version>6.8.0</version>  
</dependency>  
  1. 跨服务调用
@ServiceTask(expression = "${microserviceClient.startApproval(execution)}")  
public class MicroserviceDelegate {  
    public void startApproval(DelegateExecution ex) {  
        // 调用其他微服务  
    }  
}  
  1. 事件驱动
runtimeService.addEventListener(new EventListener() {  
    @Override  
    public void onEvent(FlowableEvent event) {  
        // 发送Kafka事件  
    }  
}, FlowableEngineEventType.TASK_COMPLETED);  
十一、运行监控方案

核心监控指标

指标监控方式
活动任务数taskService.createTaskQuery().count()
异步作业堆积量managementService.createJobQuery().count()
平均任务处理时间Micrometer + Prometheus
数据库连接池使用率HikariCP 监控

Grafana 看板配置

SELECT COUNT(*) AS active_tasks  
FROM ACT_RU_TASK  
WHERE SUSPENSION_STATE_ = 1  
十二、表达式语言高级用法
  1. 方法调用
${securityService.hasPermission(execution, 'APPROVE')}  
  1. 集合操作
${userService.findManagersByDept(deptId).stream().map(u -> u.userId).toList()}  
  1. 条件组合
${task.priority > 3 && (task.assignee == 'admin' || task.owner == 'manager')}  
十三、跨系统分布式流程设计

Saga模式实现

FlowableServiceAServiceB创建订单订单ID扣减库存结果取消订单alt[库存不足]FlowableServiceAServiceB

技术要点

  1. 使用 BPMN消息事件 触发跨系统调用
  2. 通过 补偿事件 实现回滚逻辑
  3. 事务一致性:采用最终一致性(Event Sourcing)

性能提示

  • 10,000+ TPS 场景建议启用 flowable.async.executor.threads.queue.size 缓冲队列
  • 历史表超过 1 亿行时需采用分库分表策略
  • 分布式流程推荐使用 Camunda Zeebe 或 Flowable 事件驱动模式
思维导图

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值