Activiti工作流Day18-Crystalball流程仿真
使用Activiti-Crystalball进行流程仿真
- Activiti-Crystalball简介
- CrystalBall内部
- 历史分析
- 历史的事件
- 回放
- 调试流程引擎
- 重播
Activiti-Crystalball简介
- Activiti-Crystalball(CrystalBall)是Activiti业务流程管理平台的仿真引擎 .CrystalBall可以使用用用户模拟流程场景:
- 决策支持: 对于生产流程, 比如是否应该向系统添加更多资料以达到截止日期
- 优化和验证: 测试修改并验证影响
- 培训: 模拟器可以用来在使用前培训员工
- CrystalBall是独立的:
- 不需要创建单独的模拟模型和引擎
- 不需要为模拟创建不同的报告
- 不需要为模拟引擎准备很多数据
- CrystalBall模拟器是基于Activiti的:
- 容易复制数据
- 启动模拟器
- 从历史中重播流程行为
CrystalBall内部
- CrystalBall是一个离散事件模拟器
- CrystalBall的一个实现是org.activiti.crystalball.simulator.SimpleSimulationRun:
init();SimulationEvent event = removeSimulationEvent();while (!simulationEnd(event)) {executeEvent(event);event = removeSimulationEvent();}close();
- SimulationRun可以执行由不同源生成的模拟事件
历史分析
- 模拟器可以使用的用例之一是分析历史
- 生产环境没有提供任何重复和调试bug的机会,这就是为什么基本不可能把流程引擎恢复到生产环境出现问题时完全一样的状态.有以下原因:
- 时间: 流程实例可能执行好几个月
- 并发: 流程实例会和别的实例一起运行,问题可能只产生于并发执行的情况
- 用户: 很多用户可以参与到流程实例中,流程实例会影响到出现问题的状态
- 模拟器可以更好的暴露以上的问题:
- 模拟过程是虚拟的,不会依赖真实环境
- Activiti流程引擎本身是虚拟的,不需要创建虚拟流程引擎,作为模拟环境使用
- 并发场景也是原生的
- 用户行为都会记录日志,并可以从日志重现,根据需要进行预测和生成
- 分析历史的最好办法是重现一次,真实环境很难实现重现,但是模拟器就可以实现重现
历史的事件
- 重现历史最重要的事情是记录影响状态的事件
- 流程是由用户事件驱动的,可以使用两种事件源:
- 流程实例: 只支持原始的Activiti-Crystalball项目
- ActivitiEvent日志: 可以向引擎添加想要记录日志的ActivitiEventListener. 事件日志可以保存下来,用于后续的分析
- ActivitiEventListener的一个基本实现: org.activiti.crystalball.simulator.delegate.event.impl.InMemoryRecordActivitiEventListener
@Overridepublic void onEvent(ActivitiEvent event) {Collection<SimulationEvent> simulationEvents = transform(event);store(simulationEvents);}
- 事件会被保存,可以对历史进行重现
回放
- 回放的好处是可以一遍一遍播放,直到完全理解发生了什么
- Crystalball模拟器是基于真实数据,真实用户行为
- 示例: 理解回放工作的最好方法是一步一步解释
- 基于JUnit的测试例子 :org.activiti.crystalball.simulator.delegate.event.PlaybackRunTest
<process id="theSimplestProcess" name="Without task Process"><documentation>This is a process for testing purposes</documentation><startEvent id="theStart"/><sequenceFlow id="flow1" sourceRef="theStart" targetRef="theEnd"/><endEvent id="theEnd"/></process>
流程发布,可以用于真实和模拟的运行:
- 记录事件
// get process engine with record listener to log eventsProcessEngine processEngine = (new RecordableProcessEngineFactory(THE_SIMPLEST_PROCESS, listener)).getObject();// start process instance with variablesMap<String,Object> variables = new HashMap<String, Object>();variables.put(TEST_VARIABLE, TEST_VALUE);processEngine.getRuntimeService().startProcessInstanceByKey(SIMPLEST_PROCESS, BUSINESS_KEY,variables);// check process engine status - there should be one process instance in the historycheckStatus(processEngine);// close and destroy process engineEventRecorderTestUtils.closeProcessEngine(processEngine, listener);ProcessEngines.destroy();
在startProcessInstanceByKey方法调用后,记录ActivitiEventType.ENTITY_CREATED
- 开始模拟运行:
final SimpleSimulationRun.Builder builder = new SimpleSimulationRun.Builder();// init simulation run// get process engine factory - the only difference from RecordableProcessEngineFactory that log listener is not addedDefaultSimulationProcessEngineFactory simulationProcessEngineFactory = new DefaultSimulationProcessEngineFactory(THE_SIMPLEST_PROCESS);// configure simulation runbuilder.processEngine(simulationProcessEngineFactory)// set playback event calendar from recorded events.eventCalendar(new PlaybackEventCalendarFactory(new SimulationEventComparator(), listener.getSimulationEvents()))// set handlers for simulation events.customEventHandlerMap(EventRecorderTestUtils.getHandlers());SimpleSimulationRun simRun = builder.build();simRun.execute(new NoExecutionVariableScope());// check the status - the same method which was used in record events methodcheckStatus(simulationProcessEngineFactory.getObject());// close and destroy process enginesimRun.getProcessEngine().close();ProcessEngines.destroy();
- 其它示例在org.activiti.crystalball.simulator.delegate.event.PlaybackProcessStartTest中
调试流程引擎
- 回放限制执行所有模拟事件一次性
- 调试器允许将流程事件自行拆分成更小的步骤,在步骤之间观察流程引擎的状态
- SimpleSimulationRun实现了SimulationDebugger接口 .SimulationDebugger可以一步一步执行模拟事件,可以模拟特定时间的执行:
/*** Allows to run simulation in debug mode*/public interface SimulationDebugger {/*** initialize simulation run* @param execution - variable scope to transfer variables from and to simulation run*/void init(VariableScope execution);/*** step one simulation event forward*/void step();/*** continue in the simulation run*/void runContinue();/*** execute simulation run till simulationTime*/void runTo(long simulationTime);/*** execute simulation run till simulation event of the specific type*/void runTo(String simulationEventType);/*** close simulation run*/void close();}
- 执行SimpleSimulationRunTest来观察流程引擎调试器的运行
重播
- 回放需要创建另一个流程引擎实例,模拟环境配置
- 重播工作在真实的流程引擎之上,重播在运行的流程引擎中执行模拟事件:
- 结论是重播是实时运行的,实时意味着会被立即执行**
重播一个流程实例示例: ReplyRunTest
- 第一部分 :初始化流程引擎,启动一个流程实例,完成流程实例的任务
ProcessEngine processEngine = initProcessEngine();TaskService taskService = processEngine.getTaskService();RuntimeService runtimeService = processEngine.getRuntimeService();Map<String, Object> variables = new HashMap<String, Object>();variables.put(TEST_VARIABLE, TEST_VALUE);ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(USERTASK_PROCESS, BUSINESS_KEY,variables);Task task = taskService.createTaskQuery().taskDefinitionKey("userTask").singleResult();TimeUnit.MILLISECONDS.sleep(50);taskService.complete(task.getId());
使用的流程引擎是基础的InMemoryStandaloneProcessEngine: 配置了InMemoryRecordActivitiEventListener(记录Activiti事件,并转换为模拟事件)和UserTaskExecutionListener(当创建新用户任务时,新任务会重播流程实例,把任务完成事件放到事件日历中)
- 第二部分 :在原始流程相同的引擎引擎上启动模拟调试器
- 重播事件处理器使用StartReplayProcessEventHandler替换StartProcessEventHandler
- StartReplayProcessEventHandler获取流程实例Id来重播,在流程实例启动的初始位置处理
- StartProcessEventHandler在开始阶段,会创建一个新流程实例,包含一个变量.变量名为 _replay.processInstanceId. 变量用来保存重播的流程实例Id
- 与SimpleSimulationRun不同 ,ReplaySimulationRun:
- 不会创建和关闭流程引擎实例
- 不会修改模拟时间
final SimulationDebugger simRun = new ReplaySimulationRun(processEngine,
getReplayHandlers(processInstance.getId()));
- 开始重播流程实例:
- 一开始, 没有运行的流程实例
- 只有一个已完成的,在历史中的流程实例
- 在初始化后,会在事件日历中添加一个模拟事件-用来启动流程实例,重播已经完成的流程实例
simRun.init();// original process is finished - there should not be any running process instance/taskassertEquals(0, runtimeService.createProcessInstanceQuery().processDefinitionKey(USERTASK_PROCESS).count());assertEquals(0, taskService.createTaskQuery().taskDefinitionKey("userTask").count());simRun.step();// replay process was startedassertEquals(1, runtimeService.createProcessInstanceQuery().processDefinitionKey(USERTASK_PROCESS).count());// there should be one taskassertEquals(1, taskService.createTaskQuery().taskDefinitionKey("userTask").count());
- 任务创建时,UserTaskExecutionListener会创建一个新模拟事件来结束用户任务:
simRun.step();// userTask was completed - replay process was finishedassertEquals(0, runtimeService.createProcessInstanceQuery().processDefinitionKey(USERTASK_PROCESS).count());assertEquals(0, taskService.createTaskQuery().taskDefinitionKey("userTask").count());
- 模拟结束.这时可以继续启动另一个流程实例或者事件,然后关闭simRun和流程引擎:
simRun.close();processEngine.close();ProcessEngines.destroy();
Activiti工作流Day18-Crystalball流程仿真相关推荐
- Activiti工作流与业务整合实战
Activiti工作流与业务整合实战 1. 业务背景 2.技术调研 JBPM vs Activiti选型对比 Activiti工作流特点 3.流程设计 4.架构设计 5.项目实战 5.1 maven配 ...
- SpringBoot集成activiti工作流
SpringBoot集成activiti工作流(模拟请假流程) 链接:https://pan.baidu.com/s/10BT_Zertm1WBBrlrdE-QWQ 提取码:zsq6 学习视频地址见 ...
- Activiti工作流之流程变量
1.什么是流程变量 流程变量在 activiti 中是一个非常重要的角色,流程运转有时需要靠流程变量,业务系统和 activiti 结合时少不了流程变量,流程变量就是 activiti 在管理工作流时 ...
- Activiti工作流之实现一个简单的流程审批
该代码在上一篇博客的基础上开发. Activiti工作流入门 1.绘制bpmn流程图 在resources目录下新建一个diagram文件夹来存放我们绘制的bpmn流程图 由于我的IDEA中已经安装了 ...
- 学习笔记之-Activiti7工作流引擎,概述,环境搭建,类关系图,使用Activiti BPMN visualizer,流程变量,组任务 网关,Activiti整合Spring SpringBoot
本篇学习笔记是观看黑马程序员Activiti7视频而得 Activiti7 一.工作流介绍 1.1 概念 工作流(Workflow),就是通过计算机对业务流程自动化执行管理.它主要解决的是" ...
- activiti idea 请假流程_IDEA创建Activiti工作流开发
IDEA创建Activiti工作流开发 一.安装Activiti插件 1.首先打开FIle的setting功能,搜索Plugins: 2.输入actiBPM,然后点击搜索: 3.点击安装.应用: 安装 ...
- activiti工作流,审批系统轻松落地,请假审批demo从流程绘制到审批结束实例
前言 activiti工作流,企业erp.oa.hr.crm等审批系统轻松落地,请假审批demo从流程绘制到审批结束实例. 一.项目形式 springboot+vue+activiti集成了activ ...
- Activiti工作流之流程分支
回顾: Activiti工作流之简介与环境搭建 Activiti工作流之流程部署和相关操作 Activiti工作流之任务的运行/查询/完成 Activiti工作流之流程变量 Activiti工作流之历 ...
- Java整合activiti工作流,前端适配vue,流程在线绘制设计器,适配在线表单引擎
前言 activiti工作流,企业erp.oa.hr.crm等审批系统轻松落地,请假审批demo从流程绘制到审批结束实例. 一.项目形式 springboot+vue+activiti集成了activ ...
- activiti工作流连接mysql_Activiti工作流 安装myeclipse activiti设计插件并生成数据库表...
从零开始学习Activiti工作流,记录下学习过程. 关于工作流的简介没什么好介绍了,只能说是个很有用的东西,数据库中23张表分别有什么用网上也有很详细的介绍,这里也不多加说明.activiti开发中 ...
最新文章
- C语言static 具体分析
- 停课不停学,大型网课直播翻车现场合集,你别笑,哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈啊哈...
- ubuntu 18.04 配置notebook远程连接的坑
- 普及移动办公大业,促进数字转型升级——中国移动办公专家顾问团即将盛大亮相...
- mysql 5.7.14编译安装_源码编译安装mysql-5.7.14-阿里云开发者社区
- MySQL命令之mysqlhotcopy -- 热备份
- MySQL—赋权(grant)和回收权限(revoke)
- css标签的三种显示模式
- 【BZOJ 3505】 [Cqoi2014]数三角形 容斥原理+排列组合+GCD
- git 改local branch名字_最好的Git分支管理教程
- ios获取区域服务器信息,ios获取服务器数据
- 用 js 写的 WebSocketHeartBeat,心跳检测
- 微信小程序自定义头部导航栏
- Cloudera Manager拓展SPARK2-2.3.0.cloudera3-1.cdh5.6.0.p0.1-el6.parcel
- java转大数据的学习路线
- SDUT 来淄博旅游
- 区块链技术与其在旅游行业的应用
- 微博十年 仍然稳中求胜
- 树莓派怎么运行python程序?
- 扁平化嵌套列表迭代器 [树的递归前序遍历 + 迭代前序遍历]
热门文章
- Linux基础命令---vmstat显示虚拟内存状态
- .NET回归 HTML----表单元素(1)和一些常用的标记
- 三角形状的点阵模糊效果iOS源码
- IOS开发笔记_5.线程,HTTP请求,定时器
- tensor数据类型,数据转换和新建数据操作
- 三分钟学会使用Pytorch.scatter函数
- 关闭Linux 内存地址随机化机制
- 添加本地cdrom到RHEL yum 源
- python 多继承冲突_python:super()对多继承的影响
- pythonnet 引用_Python netmiko模块的使用