Activiti工作流--分布式实现方案

一、运行环境

以下所有的描述都是基于Activiti的5.20.0.1版本

 1 public interface ProcessEngine extends EngineServices {
 2
 3   /** the version of the activiti library */
 4   public static String VERSION = "5.20.0.1";
 5
 6   /** The name as specified in ‘process-engine-name‘ in
 7    * the activiti.cfg.xml configuration file.
 8    * The default name for a process engine is ‘default */
 9   String getName();
10
11   void close();
12 }

二、Activiti不支持分布的原因分析

  1. next.dbid
  2. schema.history
  3. schema.version

其中next.dbid对应的值为数据库中当前最近一次增长后的最大记录id,每次增长的步长为2500,

1 protected int idBlockSize = 2500; (在ProcessEngineConfiguration类中)

  • Activiti中所有的id(如:Task的id,Execution的id,ProcessInstance的id等)都是通过IdGenerator来生成的
 1 /**
 2  * generates {@link IdBlock}s that are used to assign ids to new objects.
 3  *
 4  * The scope of an instance of this class is process engine,
 5  * which means that there is only one instance in one process engine instance.
 6  *
 7  * @author Tom Baeyens
 8  * @author Joram Barrez
 9  */
10 public interface IdGenerator {
11
12   String getNextId();
13
14 }
  • IdGenerator的默认实现是
 1 /**
 2  * @author Tom Baeyens
 3  */
 4 public class DbIdGenerator implements IdGenerator {
 5
 6   protected int idBlockSize;
 7   protected long nextId = 0;
 8   protected long lastId = -1;
 9
10   protected CommandExecutor commandExecutor;
11   protected CommandConfig commandConfig;
12
13   public synchronized String getNextId() {
14     if (lastId<nextId) {
15       getNewBlock();
16     }
17     long _nextId = nextId++;
18     return Long.toString(_nextId);
19   }
20
21   protected synchronized void getNewBlock() {
22     IdBlock idBlock = commandExecutor.execute(commandConfig, new GetNextIdBlockCmd(idBlockSize));
23     this.nextId = idBlock.getNextId();
24     this.lastId = idBlock.getLastId();
25   }

从上面的代码可以看出,获取下一个id的方法是加锁的,也就是在一台服务器上id的增长是没有问题的,但是如果将Activiti部署在多台服务器上就会有两个问题

  1. 从代码的第17,18行可以看出id是本地自增,如果有多台服务器就会出现id相同的情况;
  2. 获取lastId的方法是操作同一个数据库的,会有问题,代码22中通过执行GetNextIdBlockCmd来获取数据库中的next.dbid的值,如果在多台服务器上由于一台服务器修改后,其他服务器无法知道
 1 /**
 2  * @author Tom Baeyens
 3  */
 4 public class GetNextIdBlockCmd implements Command<IdBlock> {
 5
 6   private static final long serialVersionUID = 1L;
 7   protected int idBlockSize;
 8
 9   public GetNextIdBlockCmd(int idBlockSize) {
10     this.idBlockSize = idBlockSize;
11   }
12
13   public IdBlock execute(CommandContext commandContext) {
14     PropertyEntity property = (PropertyEntity) commandContext
15       .getPropertyEntityManager()
16       .findPropertyById("next.dbid");
17     long oldValue = Long.parseLong(property.getValue());
18     long newValue = oldValue+idBlockSize;
19     property.setValue(Long.toString(newValue));
20     return new IdBlock(oldValue, newValue-1);
21   }
22 }

三、解决方案

要想解决Activiti分布式的问题,就需要解决id生成的问题,也就是要自己实现IdGenerator接口,因此要有一个地方来生成一个全局唯一的id才行。

我在实际工作中是通过redis来实现的,redis也可以做集群,因此不需要考虑redis单点的问题,具体方案如下:

 1 /**
 2  * 分布式id生成器
 3  *
 4  * @version 1.0
 5  * @author Pin Xiong
 6  * @date 创建时间:2016年8月12日 下午3:22:09
 7  */
 8 public class DistributedIdGenerator implements IdGenerator {
 9
10     public DistributedIdGenerator(RedisService redisService) {
11         this.redisService = redisService;
12     }
13
14     private RedisService redisService;
15
16     @Override
17     public String getNextId() {
18         return String.format("%sX%s", D.formatDate(Constants.ACTIVITI_ENGINE_DISTRIBUTED_ID_PREFIX),this.redisService.incrby(Constants.ACTIVITI_ENGINE_DISTRIBUTED_ID_KEY, 1L));
20     }
21 }

其中,D.formatDate(Constants.ACTIVITI_ENGINE_DISTRIBUTED_ID_PREFIX)是通过服务器时间来生成id的前缀,

重点是后面的this.redisService.incrby(MainRK.ACTIVITI_ENGINE_DISTRIBUTED_ID_KEY, 1L)

该方法是在redis中获取key (也就是代码中Constants.ACTIVITI_ENGINE_DISTRIBUTED_ID_KEY)对应的值,并自增1

在实际工作中通过该方案可以解决Activiti分布式问题。

如果其他同学有更好的方案,也希望可以一起分享,谢谢!

时间: 2024-10-01 13:00:22

Activiti工作流--分布式实现方案的相关文章

Activiti工作流学习-----基于5.19.0版本(1)

该版本的Activiti运行须知: 1.JDK 6+,Eclipse最好是Kepler以上版本. 2.试验功能都有EXPERIMENTAL标注,被标注的部分不应该视为稳定的. 有兴趣的同学可以去了解下Activiti Explorer项目,他涵盖了大部分Activiti的功能,还没有Activiti概念的同学可以看看了解一下. 一.工作流开发之配置 Activiti沿用具有Spring配置文件风格的配置,工作流默认是加载名叫activiti.cfg.xml的文件,配置文件大体: <beans x

activiti工作流的web流程设计器整合视频教程 SSM和独立部署

本视频为activiti工作流的web流程设计器整合视频教程 整合Acitiviti在线流程设计器(Activiti-Modeler 5.21.0 官方流程设计器) 本视频共讲了两种整合方式 1. 流程设计器和其它工作流项目分开部署的方式 2. 流程设计器和SSM框架项目整合在一起的方式 视频大小 1.13 GB ~[获取地址] QQ313596790 本视频均为本人亲自录的,另免费附加赠送Activiti工作流视频(企业开发实例讲解) (这个赠送的Activiti工作流视频里面的流程设计器用的

Activiti工作流学习(三)Activiti工作流与spring集成

一.前言 前面Activiti工作流的学习,说明了Activiti的基本应用,在我们开发中可以根据实际的业务参考Activiti的API去更好的理解以及巩固.我们实际的开发中我们基本上都使用spring框架进行开发,现在来说明一下Activiti工作流与spring集成,Activiti工作流与spring集成还算比较简单,可以参考Activiti的API来进行整合. 二.Activiti常用的表 ---------------------------------------------部署对象

Activiti工作流笔记(2)

1.Activiti工作数据表 Activiti用来存放流程数据的表共使用23张表,表名都是以"ACT_"开头,底层操作默认使用mybatis操作 工作流Activiti的表是用来存储流程数据的,而业务的数据需要用户自己创建和维护 在使用Activiti时一定需要业务去关联流程. 以下以MySql数据库为例: 1)使用代码方式创建Activiti工作流需要的23张表 @Test public void createTable_1() { //创建流程引擎配置对象 ProcessEngi

activiti,工作流,web流程设计器,SSM,activiti工作流

本视频为activiti工作流的web流程设计器整合视频教程 整合Acitiviti在线流程设计器(Activiti-Modeler 5.21.0 官方流程设计器) 本视频共讲了两种整合方式 1. 流程设计器和其它工作流项目分开部署的方式 2. 流程设计器和SSM框架项目整合在一起的方式 视频大小 1.13 GB [获取地址] QQ313596790 本视频均为本人亲自录的,另免费附加赠送Activiti工作流视频(企业开发实例讲解) (这个赠送的Activiti工作流视频里面的流程设计器用的e

Activiti工作流学习-----基于5.19.0版本(6)

七. BPMN的简介 读者了解到这里,应付一般的工作流开发已经足够了.此处应该有华丽的分割线,在工作流项目中核心开发人员主要是对工作流业务设计以及实现,而初级开发人员是对业务功能的代码实现.以后将主要对流程图设计的概念和具体设计进行描述,如果你感兴趣可以继续了解. 7.1 什么是BPMN? BPMN的全称是Business Process Model and Notation,它是一套BPM的规范,从2004年起,BPMN规范的推动有OMG组织维护,开始推出的BPMN1.0主要是对设计图中图形的

activiti工作流的web流程设计器整合视频教程

本视频为activiti工作流的web流程设计器整合视频教程 整合Acitiviti在线流程设计器(Activiti-Modeler 5.21.0 官方流程设计器) 本视频共讲了两种整合方式 1. 流程设计器和其它工作流项目分开部署的方式 2. 流程设计器和SSM框架项目整合在一起的方式 视频大小 1.13 GB [获取地址] 本视频均为本人亲自录的,另免费附加赠送Activiti工作流视频(企业开发实例讲解) (这个赠送的Activiti工作流视频里面的流程设计器用的ecllipse的插件)

activiti工作流之Eclipse的Eclipse BPMN 2.0 Designer无法安装或者(安装后无法重复打开*.bpmn)

1.首先.既然学习activiti工作流,连官网和相应文件都没有下载就说不过去了 这是官网下载:http://www.activiti.org/download.html 2.对于下载后的activiti-5.17.0.zip的解压文件后,就很习惯去看docs/userguide/index.html 查找Chapter 12. Eclipse Designer 里面会叫如何安装Eclipse BPMN 2.0 Designer插件. Name: Activiti BPMN 2.0 design

Activiti 工作流表单设计及开发

一.前言 Activiti 5对表单的支持目前还是比较弱的,表现在对表单的开发还需要写Freemark模板,并且它的模板还需要跟class文件一起打包发布.这使得流程的表单设计必须由开发人员来开发处理.因而,开发一套易用性强的流程表单功能就显得很有必要. 二.需求 用户一般都希望能有如Microsoft的Office套件中的InfoPath那样,可以自己进行设计,并且能与工作流程绑在一起进行流转处理.如下所示: 表单中每个字段有固定的数据类型,并由不同的数据控件展示,如日期.数字.单选或多选.下