activti6——超时处理

hl.wang

发布于 2019.10.31 16:22 阅读 2832 评论 0

Activiti6概述

 

Activiti 是由 jBPM 的创建者 Tom Baeyens 离开 JBoss 之后建立的项目,构建在开发 jBPM 版本 1 到 4 时积累的多年经验的基础之上,旨在创建下一代的 BPM 解决方案。

Activiti是一个开源的工作流引擎,它实现了BPMN 2.0规范,可以发布设计好的流程定义,并通过api进行流程调度。

Activiti 作为一个遵从 Apache 许可的工作流和业务流程管理开源平台,其核心是基于Java的超快速、超稳定的 BPMN2.0 流程引擎,强调流程服务的可嵌入性和可扩展性,同时更加强调面向业务人员。

Activiti 流程引擎重点关注在系统开发的易用性和轻量性上。每一项 BPM 业务功能 Activiti 流程引擎都以服务的形式提供给开发人员。通过使用这些服务,开发人员能够构建出功能丰富、轻便且高效的 BPM 应用程序。

Activiti是一个针对企业用户、开发人员、系统管理员的轻量级工作流业务管理平台,其核心是使用Java开发的快速、稳定的BPMN e 2.0流程引擎。Activiti是在ApacheV2许可下发布的,可以运行在任何类型的Java程序中,例如服务器、集群、云服务等。Activiti可以完美地与Spring集成。同时,基于简约思想的设计使Activiti非常轻量级。
 

 

 

Activiti的特点

1)数据持久化

      Activiti的设计思想是简洁、快速。有过应用开发经验的开发人员都知道应用的瓶颈体现在和数据库交换数据的过程中,针对这一点Activiti选择了使MyBatis,从而可以通过最优的SQL语句执行Command,仅凭如此就能让引擎在速度上保持最高的性能。

2)流程设计器

      在jBPM4时代有专门的Eclipse插件可以用来设计jPDL,同样Activiti团队也专门设计了用来设计BPMN 2.0规范的流程谩计器-Eclipse Designer。此外还有Signavio公司为Activiti定制的基于Web的Activiti Modeler流程设计器。喜欢用IDEA的,IDEA也有actiBPM插件支持
 

3)原生支持Spring

      Activiti原生支持Spring,这一点对企业应用来说尤为重要:可以很轻松地进行Spring集成,非常方便管理事务和解析表达式( Expression)。

4)分离运行时与历史数据

       Activiti继承自jBPM4,在表结构设计方面也遵循运行时与历史数据的分离,这样的设计可以快速读取运行时数据,仅当需要查询历史数据时再从专门的历史数据表中读取。这种设计方式可以大幅提高数据的存取效率,尤其是当数据日积月累时依然能够快速反应。

 

 

 

提出问题

       上面我们简单的介绍了一下activiti,大家可能用过或者没有使用过activiti,当我们业务中需要满足当一个状态在规定时间内没有到下一个状态时就认定这个状态超时条件时,大家都是怎么实现的呢,下面我们我来给大家介绍一种方法

 

 

 

 

 

分析问题

       通过对activiti的了解可以知道,activiti存在时间边界事件,可以通过让一个操作定时进行到下一个操作,那么可不可以也存在超时呢?下面我们来看看能否实现超时监控处理。

 

 

 

 

 

解决问题

首先我们访问http://localhost:8080/activiti-app/#/login  输入账号密码之后登陆

 

 

 

 

进入之后点击Kickstart App

 

 

 

然后我们直接创建一个bpmn

 

 

 

取好名称和key

 

 

 

 

 

 

 

之后画好我们的流程图

 

 

 

 

最后不要忘记设置超时时间(我这里设置的是1秒)

       然后我们保存,生成配置文件,将配置文件后缀名修改为.bpmn之后通过配置文件部署activiti

 

 

 

 

 

下面我们贴出测试代码

Deployment deployment = repositoryService.createDeployment() // 创建部署
                    .addClasspathResource("testdemo.bpmn") // 加载流程资源文件
                    .name("test") //
                    .deploy(); // 部署
        System.out.println("流程部署ID:" + deployment.getId());
        System.out.println("流程部署Name:" + deployment.getName());
        MyTaskQuery myTaskQuery1 = new MyTaskQuery();
        myTaskQuery1.setBpmProcessId("testdemo");
        pi = runtimeService.startProcessInstanceByKey("processtestdemo"); // 流程定义表的KEY字段值
        List<Task> tasks2 =taskService.createTaskQuery().processInstanceId(pi.getProcessInstanceId()).list();
        System.out.println("流程实例ID:" + pi.getId());
        System.out.println("流程定义ID:" + pi.getProcessDefinitionId());
        myTaskQuery1.setProcessInstanceId(pi.getProcessInstanceId());
//        try {
//            Thread.sleep(1000 * 10);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        List<Task> tasks3 = taskService.createTaskQuery().processInstanceId(pi.getProcessInstanceId()).list();
        activitiService.propel(myTaskQuery1);
        List<Task> tasks5 = taskService.createTaskQuery().processInstanceId(pi.getProcessInstanceId()).list();
        activitiService.propel(myTaskQuery1);

 

   

 

 

 

      但是只有这样运行项目,发现并没有效果,那么我们还需要做什么呢?我们还需要编写一个监视器

public class JobEventListener implements ActivitiEventListener {
    private static final Logger LOGGER =  LoggerFactory.getLogger(JobEventListener.class);
    @Override
    public void onEvent(ActivitiEvent activitiEvent) {
        ActivitiEventType eventType = activitiEvent.getType();
        String name = eventType.name();
        if (name.equals("TIMER_FIRED")){
            System.out.println("=================================超时了==================================");
//            System.out.println("监听到job事件 {} \t {}",eventType,activitiEvent.getProcessInstanceId());
            LOGGER.info("监听到job事件 {} \t {}",eventType,activitiEvent.getProcessInstanceId());
        }
    }
    @Override
    public boolean isFailOnException() {
        return false;
    }
}

         

 

 

 

       现在监视器写好了,心急的小伙伴觉得这下子一定可以了吧,答案是否定的,我们还需要将监视器配置到spring配置文件中

<property name="eventListeners">
    <list>
        <bean class="com.jtexplorer.filter.JobEventListener"/>
    </list>
</property>

       

 

 

 

       好了现在监视器配置好了,大家觉得一定可以了吧,但是测试的时候依然发现无法做到超时监控,那么问题在哪呢?重点来了,也是我用了好久才解决的一个问题,在百度里有的说是还需要加一个标签激活job

<property name="jobExecutorActivate" value="true" />

     

 

 

       但是我这里加上这个标签是报错的,因此找了好久都没有解决这个问题,最后终于找到了解决办法,将这个标签换成

<property name="asyncExecutorActivate" value="true" />

 

 

       当换成这个标签的时候,我也是报着试试的态度,但是当我测试的时候,出乎意料的成功了

 

 

 

我们发现断点成功的进入了,控制台也成功的打印出了信息

 

 

 

总结

       其实超时处理并不是很麻烦,为什么一直无法实现,不知道大家遇到的都是什么问题,我遇到的就是asyncExecutorActivate这个标签没有配置,通过各种查询资料也没有查到使用这个标签的样例,可能很多人遇到了和我一样的问题,也在苦苦困扰,希望这篇文章可以给大家解困问题提供一点灵感和思路。