187 - 高并发性的UUID ID生成器和多租户

Posted 分享牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了187 - 高并发性的UUID ID生成器和多租户相关的知识,希望对你有一定的参考价值。

1、用于高并发性的UUID ID生成器

在某些非常高的并发负载情况下,由于无法足够快地获取新的ID块,因此缺省ID生成器可能会导致异常。每个流程引擎都有一个ID生成器。默认ID生成器在数据库中保留一个ID块,使得其他引擎不能使用来自同一块的ID。在引擎操作期间,当默认ID生成器注意到ID块被用完时,开始新事务以获取新块。在(非常)有限的使用情况下,当真正的高负载时,这可能会导致问题。对于大多数使用情况来说,默认的ID生成器已经足够了。缺省值org.flowable.engine.impl.db.DbIdGenerator还有一个属性idBlockSize,可以配置该属性来设置保留的ID块的大小,并调整ID取回的行为。

默认ID生成器的替代方案是org.flowable.engine.impl.persistence.StrongUuidGenerator,它在本地生成唯一的UUID,并将其用作所有实体的标识符。由于UUID是在不需要数据库访问的情况下生成的,因此可以更好地处理并发用例。请注意,性能可能与默认ID生成器(正面和负面)有所不同,具体取决于机器。

UUID生成器可以在Flowable配置中设置如下:

<property name="idGenerator">
<bean class="org.flowable.engine.impl.persistence.StrongUuidGenerator" />
</property>

UUID ID生成器的使用具有以下额外的依赖性:

<dependency>
<groupId>com.fasterxml.uuid</groupId>
<artifactId>java-uuid-generator</artifactId>
<version>3.1.3</version>
</dependency>

2、多租户

一般而言,多租户是软件能够为多个不同组织提供服务的概念。关键是数据是分区的,没有组织可以看到其他数据。在这种情况下,这样一个组织(或者一个部门,或者一个团队,或者别的什么的,就叫做租户。

请注意,这与多实例安装程序(其中Flowable Process引擎实例正在为每个组织单独运行(并使用不同的数据库架构))有根本的不同。虽然Flowable是轻量级的,并且运行Process Engine实例不需要太多资源,但确实增加了复杂性和更多的维护。但是,对于一些使用情况来说,这可能是正确的解决方案。

在Flowable中多租户主要是围绕数据分区来实现的。请注意,Flowable不强制执行多租户规则。这意味着在查询和使用数据时不会验证执行操作的用户是否属于正确的租户。这应该在调用Flowable引擎的层中完成。Flowable确保在检索过程数据时可以存储和使用租户信息。

将流程定义部署到Flowable Process引擎时,可以传递租户标识符。这是一个字符串(例如UUID,部门ID等),限制为256个字符,唯一标识租户:

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

在部署期间传递租户ID具有以下含义:

  • 包含在部署中的所有流程定义将继承此部署中的租户标识符。
  • 从这些流程定义开始的所有流程实例从流程定义中继承此租户标识符。
  • 执行流程实例时在运行时创建的所有任务将从流程实例继承此租户标识符。独立任务也可以有一个租户标识符。
  • 在流程实例执行期间创建的所有执行从流程实例中继承此租户标识符。
  • 可以在提供租户标识符的同时触发信号抛出事件(在流程本身或通过PI)。该信号只能在租户上下文中执行:即如果有多个同名的信号捕获事件,则实际上只会调用具有正确租户标识的信号。
  • 所有作业(定时器和异步继续)从流程定义(例如定时器启动事件)或流程实例(在作业在运行时创建,例如异步继续)继承承租人标识符。这可能会被用来优先考虑一些定制的工作执行者的租户。
  • 所有历史实体(历史流程实例,任务和活动)都从其运行时对象继承了租户标识符。
  • 作为一个方面说明,模型也可以有一个租户标识符(模型被Flowable建模者用来存储BPMN 2.0模型)。

为了实际利用流程数据上的租户标识符,所有查询API都可以在租户上进行过滤。例如(可以被其他实体的相关查询实现替换):

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

查询API也允许用类似的语义过滤租户标识符,也可以过滤掉没有租户标识的实体。

重要的实现细节:由于数据库怪癖(更具体地说:在唯一约束中的空处),指示没有租户的默认承租人标识符值是空字符串。(流程定义键,流程定义版本,租户标识符)的组合必须是唯一的(并且有一个数据库约束检查这个)。另请注意,租户标识符不应设置为空,因为这将影响查询,因为某些数据库(Oracle)将空字符串视为空值(这就是为什么查询 .withoutTenantId检查空字符串或null)。这意味着可以为多个租户部署相同的流程定义(具有相同的流程定义键),每个租户都有自己的版本。这不会影响不使用租赁时的使用情况。

请注意,以上所有内容与在群集中运行多个可流式实例都没有冲突。

(String deploymentId,String newTenantId)方法来更改租户标识符。这将改变之前被继承的任何地方的租户标识符。从非多租户设置转到多租户配置时,这非常有用。有关更多详细信息,请参阅Javadoc的方法。

上面文章来自盘古BPM研究院:http://vue.pangubpm.com/
文章翻译提交:https://github.com/qiudaoke/flowable-userguide
了解更多文章可以关注微信公众号:

以上是关于187 - 高并发性的UUID ID生成器和多租户的主要内容,如果未能解决你的问题,请参考以下文章

zookeepeer ID生成器

高并发id生产策略

java UUID.randomUUID()自动生成主键作为Id或文件路径

zookeeper全局唯一id生成

分布式问题

分布式ID生成器