配置
创建 CmmnEngine
Flowable CMMN 引擎通过一个名为 flowable.cmmn.cfg.xml 的 XML 文件进行配置。注意,如果你使用以 Spring 方式构建流程引擎,则这一方式不适用。
获取 CmmnEngine 最简单的方式是使用 org.flowable.cmmn.engine.CmmnEngineConfiguration 类:
CmmnEngine cmmnEngine = CmmnEngineConfiguration.createStandaloneCmmnEngineConfiguration();
这将在 classpath 上查找 flowable.cmmn.cfg.xml 文件,并根据该文件中的配置构建一个引擎。下面的代码片段展示了一个配置示例。后续小节将详细介绍各个配置属性。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cmmnEngineConfiguration" class="org.flowable.cmmn.engine.CmmnEngineConfiguration">
<property name="jdbcUrl" value="jdbc:h2:mem:flowable;DB_CLOSE_DELAY=1000" />
<property name="jdbcDriver" value="org.h2.Driver" />
<property name="jdbcUsername" value="sa" />
<property name="jdbcPassword" value="" />
<property name="databaseSchemaUpdate" value="true" />
</bean>
</beans>
注意,配置 XML 实际上是一个 Spring 配置。这并不意味着 Flowable 只能在 Spring 环境中使用! 我们只是在内部利用 Spring 的解析和依赖注入能力来构建引擎。
CmmnEngineConfiguration 对象也可以编程方式结合配置文件创建。也可以使用不同的 bean id(例如,参见第 3 行)。
CmmnEngineConfiguration.
createCmmnEngineConfigurationFromResourceDefault();
createCmmnEngineConfigurationFromResource(String resource);
createCmmnEngineConfigurationFromResource(String resource, String beanName);
createCmmnEngineConfigurationFromInputStream(InputStream inputStream);
createCmmnEngineConfigurationFromInputStream(InputStream inputStream, String beanName);
也可以不使用配置文件,而是基于默认值创建配置(更多信息请参见所支持的不同类)。
CmmnEngineConfiguration.createStandaloneCmmnEngineConfiguration();
CmmnEngineConfiguration.createStandaloneInMemCmmnEngineConfiguration();
所有这些 CmmnEngineConfiguration.createXXX() 方法都会返回一个 CmmnEngineConfiguration,必要时可以进一步调整它。调用 buildCmmnEngine() 操作之后,就会创建出一个 CmmnEngine:
CmmnEngine cmmnEngine = CmmnEngineConfiguration.createStandaloneInMemCmmnEngineConfiguration()
.setDatabaseSchemaUpdate(CmmnEngineConfiguration.DB_SCHEMA_UPDATE_TRUE)
.setJdbcUrl("jdbc:h2:mem:my-own-db;DB_CLOSE_DELAY=1000")
.buildCmmnEngine();
CmmnEngineConfiguration Bean
flowable.cmmn.cfg.xml 必须包含一个 id 为 'cmmnEngineConfiguration' 的 bean。
<bean id="cmmnEngineConfiguration" class="org.flowable.cmmn.engine.CmmnEngineConfiguration">
该 bean 随后被用来构建 CmmnEngine。有多个可用的类可用于定义 cmmnEngineConfiguration。这些类代表不同的环境,并相应地设置默认值。最佳实践是选择最匹配你环境的类,以最大限度减少配置引擎所需的属性数量。当前可用的类如下:
- org.flowable.cmmn.engine.impl.cfg.StandaloneInMemCmmnEngineConfiguration:这是一个为单元测试提供便利的类。Flowable 会负责所有事务。默认使用 H2 内存数据库。数据库会在引擎启动时创建、关闭时删除。使用此类时,很可能不需要任何额外配置。
- org.flowable.cmmn.spring.SpringCmmnEngineConfiguration:当 CMMN 引擎在 Spring 环境中使用时使用。更多信息请参见Spring 集成小节。
数据库配置
配置 Flowable CMMN 引擎所使用的数据库有两种方式。第一种方式是定义数据库的 JDBC 属性:
- jdbcUrl:数据库的 JDBC URL。
- jdbcDriver:针对特定数据库类型的驱动实现。
- jdbcUsername:连接数据库的用户名。
- jdbcPassword:连接数据库的密码。
根据所提供的 JDBC 属性构建的数据源将使用默认的 MyBatis 连接池设置。可以选择性地设置以下属性来调整该连接池(取自 MyBatis 文档):
- jdbcMaxActiveConnections:任意时刻处于活动(即正在使用)状态的连接数。默认值为 10。
- jdbcMaxIdleConnections:任意时刻的空闲连接数。
- jdbcMaxCheckoutTime:一个连接从连接池中被"检出"后、在被强制归还之前允许的时间长度,单位为毫秒。默认值为 20000(20 秒)。
- jdbcMaxWaitTime:这是一个底层设置,当获取连接耗时异常过长时,它让连接池有机会打印日志状态并重试获取连接(以避免在连接池配置错误时永远静默失败)。默认值为 20000(20 秒)。
数据库配置示例:
<property name="jdbcUrl" value="jdbc:h2:mem:flowable;DB_CLOSE_DELAY=1000" />
<property name="jdbcDriver" value="org.h2.Driver" />
<property name="jdbcUsername" value="sa" />
<property name="jdbcPassword" value="" />
我们的基准测试表明,MyBatis 连接池在处理大量并发请求时并非最高效或最健壮。因此,建议使用 javax.sql.DataSource 实现并将其注入流程引擎配置中(例如 HikariCP、Tomcat JDBC Connection Pool 等):
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/flowable" />
<property name="username" value="flowable" />
<property name="password" value="flowable" />
<property name="defaultAutoCommit" value="false" />
</bean>
<bean id="cmmnEngineConfiguration" class="org.flowable.cmmn.engine.CmmnEngineConfiguration">
<property name="dataSource" ref="dataSource" />
...
注意,Flowable 并未附带用于定义此类数据源的库。因此你需要确保相关库位于你的 classpath 上。
无论使用 JDBC 方式还是数据源方式,都可以设置以下属性:
- databaseType:通常不需要指定该属性,因为它会从数据库连接元数据中自动检测。仅当自动检测失败时才应手动指定。可选取值:{h2, mysql, oracle, postgres, mssql, db2}。该设置将决定使用哪些建表/删表脚本和查询。支持哪些类型的概览请参见'支持的数据库'小节。
- databaseSchemaUpdate:设置在流程引擎启动和关闭时处理数据库 schema 的策略。
- false(默认值):在创建流程引擎时对照库检查数据库 schema 的版本,版本不匹配则抛出异常。
- true:在构建流程引擎时执行检查,并在必要时更新 schema。如果 schema 不存在,则创建它。
- create-drop:在创建流程引擎时创建 schema,在关闭流程引擎时删除 schema。
JNDI 数据源配置
默认情况下,Flowable 的数据库配置位于每个 Web 应用 WEB-INF/classes 下的 db.properties 文件中。这并不总是理想的,因为它要求用户要么修改 Flowable 源码中的 db.properties 并重新编译 WAR 文件,要么解包 WAR 并在每次部署时修改 db.properties。
通过使用 JNDI(Java 命名与目录接口)获取数据库连接,连接完全由 Servlet 容器管理,配置也可以在 WAR 部署之外进行管理。相比 db.properties 文件所提供的方式,这还允许对连接参数进行更多控制。
配置
JNDI 数据源的配置方式会因所使用的 Servlet 容器而异。下面的说明适用于 Tomcat,但对于其他容器应用,请参阅你所用容器的文档。
如果使用 Tomcat,JNDI 资源在 $CATALINA_BASE/conf/[enginename]/[hostname]/[warname].xml 中配置(对于 Flowable UI,通常是 $CATALINA_BASE/conf/Catalina/localhost/flowable-app.xml)。默认上下文是在应用首次部署时从 Flowable WAR 文件复制的,因此如果它已经存在,你需要替换它。例如,要将 JNDI 资源改为让应用连接 MySQL 而非 H2,可将文件改为如下内容:
<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/flowable-app">
<Resource auth="Container"
name="jdbc/flowableDB"
type="javax.sql.DataSource"
description="JDBC DataSource"
url="jdbc:mysql://localhost:3306/flowable"
driverClassName="com.mysql.jdbc.Driver"
username="sa"
password=""
defaultAutoCommit="false"
initialSize="5"
maxWait="5000"
maxActive="120"
maxIdle="5"/>
</Context>
JNDI 属性
要配置 JNDI 数据源,请在 Flowable UI 的 properties 文件中使用以下属性:
- spring.datasource.jndi-name=:数据源的 JNDI 名称。
- datasource.jndi.resourceRef:设置是否在 J2EE 容器中进行查找,例如,如果 JNDI 名称中尚未包含前缀 "java:comp/env/",则需要添加它。默认值为 "true"。
自定义属性
系统属性也可以在 flowable.cmmn.cfg.xml 中使用,格式为 $\{propertyName:defaultValue}。
<property name="jdbcUrl" value="${jdbc.url:jdbc:h2:mem:flowable;DB_CLOSE_DELAY=1000}" />
<property name="jdbcDriver" value="${jdbc.driver:org.h2.Driver}" />
<property name="jdbcUsername" value="${jdbc.username:sa}" />
<property name="jdbcPassword" value="${jdbc.password:}" />
采用此配置时,如果属性 jdbc.url 可用,它将被用于 CmmnEngineConfiguration 的 jdbcUrl。否则将使用第一个 : 之后的值。
也可以通过使用一个 org.springframework.beans.factory.config.PropertyPlaceholderConfigurer 类型的 bean 来定义从系统中读取属性的位置。
自定义属性读取位置的配置示例
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:/opt/conf/flowable.properties" />
</bean>
<bean id="cmmnEngineConfiguration" class="org.flowable.cmmn.engine.CmmnEngineConfiguration">
<property name="jdbcUrl" value="${jdbc.url:jdbc:h2:mem:flowable;DB_CLOSE_DELAY=1000}" />
<property name="jdbcDriver" value="${jdbc.driver:org.h2.Driver}" />
<property name="jdbcUsername" value="${jdbc.username:sa}" />
<property name="jdbcPassword" value="${jdbc.password:}" />
<property name="databaseSchemaUpdate" value="true" />
</bean>
</beans>
采用此配置时,将首先在 /opt/conf/flowable.properties 文件中查找属性。
支持的数据库
下面列出了 Flowable 用于指代数据库的类型(区分大小写!)。
| Flowable 数据库类型 | 示例 JDBC URL | 说明 |
|---|---|---|
| h2 | jdbc:h2:tcp://localhost/flowable | 默认配置的数据库 |
| mysql | jdbc:mysql://localhost:3306/flowable?autoReconnect=true | 使用 mysql-connector-java 数据库驱动测试 |
| oracle | jdbc:oracle:thin:@localhost:1521:xe | |
| postgres | jdbc:postgresql://localhost:5432/flowable | |
| db2 | jdbc:db2://localhost:50000/flowable | |
| mssql | jdbc:sqlserver://localhost:1433;databaseName=flowable (jdbc.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver) OR jdbc:jtds:sqlserver://localhost:1433/flowable (jdbc.driver=net.sourceforge.jtds.jdbc.Driver) | 使用 Microsoft JDBC Driver 4.0(sqljdbc4.jar)和 JTDS 驱动测试 |
创建数据库表
为你的数据库创建数据库表最 简单的方式是:
- 将 flowable-cmmn-engine JAR 添加到你的 classpath
- 添加合适的数据库驱动
- 将一个 Flowable 配置文件(flowable.cmmn.cfg.xml)添加到你的 classpath,使其指向你的数据库(参见数据库配置小节)
- 执行 DbSchemaCreate 类的 main 方法
然而,通常只有数据库管理员才能在数据库上执行 DDL 语句。在生产系统上,这也是最明智的选择。SQL DDL 语句可以在 Flowable 下载页面找到,也可以在 Flowable 发行版文件夹的 database 子目录中找到。这些脚本也包含在引擎 JAR(flowable-cmmn-engine-x.jar)的 org/flowable/cmmn/db/create 包中。SQL 文件的命名格式为:
flowable.{db}.cmmn.create.sql
其中 db 是任意一种支持的数据库。
数据库表名说明
Flowable CMMN 引擎的所有数据库表名都以 ACT_CMMN_ 开头。第二部分是一个两位字符的标识,用于表示该表的用途。该用途也大致与服务 API 相对应。
- ACT_CMMN_*:没有额外前缀的表包含"静态"信息,例如用例定义和用例资源(图片、规则等)。
- ACT_CMMN_RU_*:"RU" 代表 runtime(运行时)。这些是运行时表,包含用例实例、计划项等的运行时数据。Flowable 只在用例实例执行期间存储运行时数据,并在用例实例结束时删除这些记录。这使得运行时表保持小巧、快速。
- ACT_CMMN_HI_*:"HI" 代表 history(历史)。这些表包含历史数据,例如过去的用例实例、计划项等。
数据库升级
在执行升级之前,请务必(利用你的数据库备份功能)备份数据库。
默认情况下,每次创建流程引擎时都会执行一次版本检查。这通常发生在你的应用或 Flowable Web 应用启动时。如果 Flowable 库检测到库版本与 Flowable 数据库表版本不一致,就会抛出异常。
要进行升级,首先需要在你的 flowable.cmmn.cfg.xml 配置文件中加入以下配置属性:
<beans >
<bean id="cmmnEngineConfiguration"
class="org.flowable.cmmn.engine.CmmnEngineConfiguration">
<!-- ... -->
<property name="databaseSchemaUpdate" value="true" />
<!-- ... -->
</bean>
</beans>
此外,请将适合你数据库的驱动加入 classpath。 升级应用中的 Flowable 库。或者启动一个新版本的 Flowable,并将其指向一个包含旧版本数据的数据库。当 databaseSchemaUpdate 设置为 true 时,Flowable 在第一次检测到库与数据库 schema 不同步时,会自动将数据库 schema 升级到最新版本。
作为另一种选择,你也可以运行升级 DDL 语句。 也可以运行 Flowable 下载页面上提供的升级数据库脚本。
历史配置
<property name="history" value="audit" />
在表达式和脚本中暴露配置 Bean
默认情况下,你在 flowable.cmmn.cfg.xml 配置或自己的 Spring 配置文件中指定的所有 bean 都可被表达式和脚本使用。如果想限制配置文件中 bean 的可见性,可以在流程引擎配置中配置一个名为 beans 的属性。CmmnEngineConfiguration 中的 beans 属性是一个 map。指定该属性后,只有该 map 中指定的 bean 才能被表达式和脚本看到。暴露的 bean 将以你在 map 中指定的名称暴露。
部署缓存配置
所有用例定义都会(在解析后)被缓存,以避免每次需要用例定义时都访问数据库,也因为用例定义数据不会改变。默认情况下,该缓存没有限制。要限制用例定义缓存,请添加以下属性:
<property name="caseDefinitionCacheLimit" value="10" />
设置此属性将把默认的 hashmap 缓存替换为一个具有所设硬上限的 LRU 缓存。当然,该属性的"最佳"取值取决于所存储的用例定义总数,以及所有运行时用例实例在运行时实际使用的用例定义数量。
你也可以注入自己的缓存实现。它必须是一个实现了 org.flowable.engine.common.impl.persistence.deploy.DeploymentCache 接口的 bean:
<property name="caseDefinitionCache">
<bean class="org.flowable.MyCache" />
</property>
日志
所有日志(flowable、spring、mybatis 等)都通过 SLF4J 路由,并允许选择你喜欢的日志实现。
默认情况下,flowable-cmmn-engine 依赖中不包含任何 SFL4J 绑定 JAR,你需要在自己的项目中添加它,才能使用所选的日志框架。 如果不添加实现 JAR,SLF4J 将使用一个 NOP 日志记录器,除了发出"将不记录任何日志"的警告外什么都不记录。有关这些绑定的更多信息,请参见 http://www.slf4j.org/codes.html#StaticLoggerBinder。
使用 Maven 时,例如添加如下依赖(这里使用 log4j),注意你仍然需要添加版本号:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-reload4j</artifactId>
</dependency>
flowable-rest Web 应用配置为使用 Log4j 绑定。运行所有 flowable-* 模块的测试时也会使用 Log4j。
在 classpath 中包含 commons-logging 的容器上使用时请注意: 为了将 spring 日志通过 SLF4J 路由,需要使用一个桥接器(参见 http://www.slf4j.org/legacy.html#jclOverSLF4J)。如果你的容器提供了 commons-logging 实现,请按照此页面 http://www.slf4j.org/codes.html#release 上的说明操作,以确保稳定性。
使用 Maven 时的示例(省略版本号):
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</dependency>