《工作流》flowable实现多租户

多租户

总的来说,多租户是指一个软件为多个不同组织提供服务。其核心是数据隔离,一个组织不能看到其他组织的数据。在这个语境中,一个这样的组织(或部门、团队,等等)被称为一个租户(tenant)

请注意它与多实例部署有本质区别。多实例部署是指每一个组织都分别运行一个Flowable流程引擎实例(且使用不同的数据库账户)。尽管Flowable比较轻量级,运行一个流程引擎实例不会花费太多资源,但多实例部署仍然增加了复杂度与维护量。但是,在某些使用场景中,多实例部署可能是正确的解决方案。

Flowable中的多租户主要围绕着隔离数据实现。要注意Flowable并不强制多租户规则。换句话说,查询与使用数据时,不会验证进行操作的用户是否属于正确的租户。这应该在调用Flowable引擎的层次实现。Flowable负责确保可以存储租户信息,并可在获取流程数据时使用。

在Flowable流程引擎中部署流程定义时,可以传递一个租户标识符(tenant identifier)。这是一个字符串(可以是UUID,部门id,等等……),限制为256个字符长,唯一标识一个租户:

repositoryService.createDeployment()
    .addClassPathResource(...)
    .tenantId("myTenantId")
    .deploy();


部署中包含的所有流程定义都将从该部署继承租户标识符。在部署时传入一个租户ID意味着:

  • 从这些流程定义启动的所有流程实例都将从流程定义继承租户标识符。

  • 在执行流程实例时,创建所有任务都将从流程实例继承租户标识符。独立任务也可以有租户标识符。

  • 执行流程实例时,创建的所有执行都将从流程实例继承租户标识符。

  • (在流程内或通过API)触发信号抛出事件时可以提供租户标识符。这个信号将只在该租户的上下文中执行。也就是说,如果有多个使用相同名字的信号捕获事件,只会触发带有正确租户标识符的捕获事件。

  • 所有作业(定时器与异步操作)要么从流程定义(如定时器启动事件),要么从流程实例(运行时创建的作业,如异步操作)继承租户标识符。这样就可以在自定义作业执行器中,为租户设置优先级。

  • 所有历史实体(历史流程实例、任务与活动)都从其对应的运行时对象继承租户标识符。

  • 另外,模型也可以有租户标识符(模型用于Flowable Modeler存储BPMN 2.0)。

所有查询API都可以通过租户标识符进行过滤。例如(也可以换成其他实体的查询):

runtimeService.createProcessInstanceQuery()
    .processInstanceTenantId("myTenantId")
    .processDefinitionKey("myProcessDefinitionKey")
    .variableValueEquals("myVar", "someValue") .list() 

查询API也可以使用like语义通过租户标识符过滤,也可以过滤掉没有租户标识符的实体。

重要的实现细节:由于数据库的原因(更确切地说,对唯一约束中null的处理),默认的代表没有租户的租户标识符为空字符串。这是因为(流程定义key,流程定义版本,租户标识符)的组合需要是唯一的(由数据库约束保证)。也请注意租户标识符不能设置为null,不然会影响查询,因为某些数据库(Oracle)会将空字符串当做null值处理(这也就是为什么.withoutTenantId查询不检查空字符串还是null)。所以可以为多个租户部署(有相同的流程定义key的)同一个流程定义,并且每一个租户都有他们自己的版本。不影响未使用租户时的使用方式。

请注意,集群运行多个Flowable实例与上面所说不冲突。

[实验性] 可以调用repositoryServicechangeDeploymentTenantId(String deploymentId, String newTenantId)方法修改租户标识符。并将连带修改每一处之前继承的租户标识符。在从非多租户环境迁移至多租户部署时很有用。查看该方法的Javadoc了解更多信息。

你可能感兴趣的:(java)