Flowable 6.6.0 BPMN用户指南 - 17 高级用例 - 17.3、4

《Flowable 6.6.0 BPMN用户指南》

1. 入门
2. 配置
3 The Flowable API
4 Flowable 6.6.0 BPMN用户指南 - (4)Spring集成
5 Spring Boot
6 部署
7 BPMN 2.0简介
8 BPMN 2.0的构造
9 表单(Forms)
10 流程实例迁移
11 JPA
12 历史(History)
13 身份管理(Identity management)
14 REST API
15 CDI集成
16 LDAP集成
17 高级用例
  • 17.1 异步执行器(Async Executor)
    • 17.1.1 异步执行器设计(Async Executor design)
    • 17.1.2 异步执行器配置
    • 17.1.3 基于异步执行器的消息队列
  • 17.2 与流程解析挂钩(Hooking into process parsing)
  • 17.3 用于高并发的UUID ID生成器
  • 17.4 多租户(Multitenancy)
  • 17.5 执行自定义SQL(Execute custom SQL)
  • 17.6 采用ProcessEngineConfigurator 进行高级的流程引擎配置
  • 17.7 高级查询API:运行时和历史任务查询之间的无缝切换
  • 17.8 重写标准SessionFactory实现自定义身份管理
  • 17.9 启用安全的BPMN 2.0 xml
  • 17.10 事件日志记录(Event logging)
  • 17.11 禁用批量插入(Disabling bulk inserts)
  • 17.12 安全脚本(Secure Scripting)
  • 17.13 日志记录会话[实验性]

有关Flowable的更多文档,参见:

《Flowable文档大全》


17.3 用于高并发的UUID ID生成器

In some (very) high concurrency load cases, the default ID generator may cause exceptions due to not being able to fetch new ID blocks quickly enough. Every process engine has one ID generator. The default ID generator reserves a block of IDs in the database, such that no other engine will be able to use IDs from the same block. During engine operations, when the default ID generator notices that the ID block is used up, a new transaction is started to fetch a new block. In (very) limited use cases this can cause problems when there is a real high load. For most use cases the default ID generator is more than sufficient. The default org.flowable.engine.impl.db.DbIdGenerator also has a property idBlockSize which can be configured to set the size of the reserved block of IDs and to tweak the behavior of the ID fetching.

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

The alternative to the default ID generator is the org.flowable.engine.impl.persistence.StrongUuidGenerator, which generates a unique UUID locally and uses that as an identifier for all entities. Since the UUID is generated without the need for database access, it copes better with very high concurrency use cases. Do note that performance may differ from the default ID generator (both positive and negative) depending on the machine.
The UUID generator can be set up in the Flowable configuration as follows:

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

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

<property name="idGenerator">
    <bean class="org.flowable.engine.impl.persistence.StrongUuidGenerator" />
</property>
The use of the UUID ID generator has the following extra dependency:
 <dependency>
    <groupId>com.fasterxml.uuid</groupId>
    <artifactId>java-uuid-generator</artifactId>
    <version>3.1.3</version>
</dependency>

17.4 多租户(Multitenancy)

Multitenancy in general is a concept where the software is capable of serving multiple different organizations. Key is that the data is partitioned and no organization can see the data of other ones. In this context, such an organization (or a department, or a team or whatever, is called a tenant.

Note that this is fundamentally different from a multi-instance setup, where a Flowable Process engine instance is running for each organization separately (and with a different database schema). Although Flowable is lightweight, and running a Process Engine instance doesn’t take much resources, it does add complexity and more maintenance. But, for some use cases it might be the right solution.

多租户通常是指软件能够为多个不同的组织提供服务的概念。关键是数据是分区的,没有组织可以看到其他组织的数据。在这种情况下,这样的组织(或部门、团队或其他任何东西)被称为租户(tenant)。

请注意,这与多实例设置有根本不同,多实例设置为每个组织分别运行一个Flowable流程引擎实例(并且使用不同的数据库schema)。尽管Flowable是轻量级的,并且运行流程引擎实例不需要太多资源,但它确实增加了复杂性和更多的维护。但是,对于某些用例,这可能是正确的解决方案。

Multitenancy in Flowable is mainly implemented around partitioning the data. It is important to note that Flowable does not enforce multi tenancy rules. This means it will not verify when querying and using data whether the user doing the operation belongs to the correct tenant. This should be done in the layer calling the Flowable engine. Flowable does make sure that tenant information can be stored and used when retrieving process data.

When deploying process definition to the Flowable Process engine it is possible to pass a tenant identifier. This is a string (e.g. a UUID, department id, etc.), limited to 256 characters which uniquely identifies the tenant:

Flowable中的多租户主要是围绕数据分区来实现的。需要注意的是,Flowable不强制执行多租户规则。这意味着它在查询和使用数据时不会验证执行操作的用户是否属于正确的租户。这应该在调用Flowable引擎的层中完成。Flowable确保在检索流程数据时可以存储和使用租户信息。
将流程定义部署到Flowable流程引擎时,可以传递租户标识符(tenant identifier)。这是一个字符串(例如UUID、部门id等),限制为256个字符,唯一地标识租户:

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

Passing a tenant ID during a deployment has following implications:

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

  • All the process definitions contained in the deployment inherit the tenant identifier from this deployment.
  • All process instances started from those process definitions inherit this tenant identifier from the process definition.
  • All tasks created at runtime when executing the process instance inherit this tenant identifier from the process instance. Standalone tasks can have a tenant identifier too.
  • 部署中包含的所有流程定义都从该部署继承租户标识符。
  • 从这些流程定义启动的所有流程实例都从流程定义继承此租户标识符。
  • 执行流程实例时在运行时创建的所有任务都从流程实例继承此租户标识符。独立任务(Standalone task)也可以有租户标识符。
  • All executions created during process instance execution inherit this tenant identifier from the process instance.
  • Firing a signal throw event (in the process itself or through the API) can be done whilst providing a tenant identifier. The signal will only be executed in the tenant context: i.e. if there are multiple signal catch events with the same name, only the one with the correct tenant identifier will actually be called.
  • All jobs (timers and async continuations) inherit the tenant identifier from either the process definition (e.g. timer start event) or the process instance (when a job is created at runtime, e.g. an async continuation). This could potentially be used for giving priority to some tenants in a custom job executor.
  • 在流程实例执行期间创建的所有执行从流程实例继承此租户标识符。
  • 可以在提供租户标识符的同时触发信号抛出事件(在流程本身或通过API)。信号将只在租户上下文中执行:也就是说,如果有多个具有相同名称的信号捕获事件,那么实际上只调用具有正确租户标识符的事件。
  • 所有作业(定时器和异步持续)从流程定义(例如计时器启动事件)或流程实例(在运行时创建作业时,例如异步持续)继承租户标识符。这可能用于在自定义作业执行器中为某些租户赋予优先级。
  • All the historic entities (historic process instance, task and activities) inherit the tenant identifier from their runtime counterparts.
  • As a side note, models can have a tenant identifier too (models are used e.g. by the Flowable modeler to store BPMN 2.0 models).
  • 所有历史实体(历史流程实例、任务和活动)从其运行时对应对象中继承租户标识符。
  • 作为补充说明,模型也可以有一个租户标识符(例如,Flowable modeler用于存储BPMN 2.0模型的模型来)。

To actually make use of the tenant identifier on the process data, all the query API’s have the capability to filter on tenant. For example (and can be replaced by the relevant query implementation of the other entities):

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

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

The query API’s also allow to filter on the tenant identifier with like semantics and also to filter out entities without tenant id.

Important implementation detail: due to database quirks (more specifically: null handling in unique constraints) the default tenant identifier value indicating no tenant is the empty string. The combination of (process definition key, process definition version, tenant identifier) needs to be unique (and there is a database constraint checking this). Also note that the tenant identifier shouldn’t be set to null, as this will affect the queries since certain databases (Oracle) treat empty string as a null value (that’s why the query .withoutTenantId does a check against the empty string or null). This means that the same process definition (with same process definition key) can be deployed for multiple tenants, each with their own versioning. This does not affect the usage when tenancy is not used.

查询API还允许使用like (相似)语义过滤租户标识符,也可以过滤出没有租户id的实体。

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

Do note that all of the above does not conflict with running multiple Flowable instances in a cluster.

[Experimental] It is possible to change the tenant identifier by calling the changeDeploymentTenantId(String deploymentId, String newTenantId) method on the repositoryService. This will change the tenant identifier everywhere it was inherited before. This can be useful when going from a non-multitenant setup to a multitenant configuration. See the Javadoc on the method for more detailed information.

请注意,以上所有操作与在集群中运行多个Flowable实例并不冲突。

[实验性]通过调用repositoryService上的changeDeploymentTenantId(String deploymentId, String newTenantId)方法,可以更改租户标识符。这将更改以前继承的所有租户标识符。这在从非多租户设置转换为多租户配置时非常有用。有关更多详细信息,请参阅关于该方法的Javadoc。

你可能感兴趣的:(Flowable,6.6.0,BPMN用户指南,-9-18)