66.2. 运行时管理器
RuntimeManager 类在进程引擎 API 中提供一个层,可简化并赋予其使用情况。此类封装和管理 KIE 基础和 KIE 会话,以及为进程中的所有任务提供处理程序的任务服务。运行时管理器中的 KIE 会话和任务服务已配置为彼此使用,您不需要提供这样的配置。例如,您不需要注册人工任务处理程序,并确保它连接到所需的服务。
运行时管理器根据预定义的策略管理 KIE 会话。可用的策略如下:
-
singleton :运行时管理器维护一个
KieSession,并将其用于所有请求的进程。 -
每个请求 :运行时管理器为每个请求创建一个新的
KieSession。 -
每个进程 实例 :运行时管理器在进程实例和
KieSession之间维护映射,每当使用给定进程实例时始终提供相同的KieSession。
无论策略是什么,RuntimeManager 类都在进程引擎组件初始化和配置确保相同的功能:
-
KieSession实例使用相同的工厂(基于内存或 JPA)加载的实例。 -
work item 处理程序在每个
KieSession实例中注册(从数据库加载或新创建)。 -
事件监听程序(
进程、Agenda和WorkingMemory)在每个 KIE 会话中注册,无论会话是否从数据库加载,还是从数据库加载。 任务服务被配置为以下所需组件:
- JTA 事务管理器
-
与用于
KieSession实例使用的实体管理器工厂相同 -
可以在环境中配置的
UserGroupCallback实例
运行时管理器还启用对进程引擎的完全处理。它提供了在不再需要时分散 RuntimeEngine 实例的专用方法,释放它可能获取的所有资源。
以下代码显示了 RuntimeManager 接口的定义:
RuntimeManager 接口的定义
RuntimeManager 类还提供 RuntimeEngine 类,它包括访问底层进程引擎组件的方法:
RuntimeEngine 接口的定义
RuntimeManager 类的标识符在运行时执行过程中用作 deploymentId。例如,当 任务 持久化时,标识符会被保留为 任务的 deploymentId。任务的 deploymentID 在任务完成时将其与 RuntimeManager 关联,进程实例会恢复。
相同的 deploymentId 也作为 externalId 在历史记录日志表中保留。
如果您在创建 RuntimeManager 实例时不指定标识符,则根据策略应用默认值(例如,对于 PerProcessInstanceRuntimeManager)。这意味着您的应用程序在其整个生命周期中使用与 RuntimeManager 类相同的部署。
如果在应用程序中维护多个运行时管理器,您必须为每个 RuntimeManager 实例指定一个唯一标识符。
例如,部署服务维护多个运行时管理器,并使用 KJAR 文件的 GAV 值作为标识符。相同的逻辑在 Business Central 和 KIE 服务器中使用,因为它们依赖于部署服务。
当您需要从处理程序或侦听器中与进程引擎或任务服务交互时,您可以使用 RuntimeManager 界面获取给定进程的 RuntimeEngine 实例,然后使用 RuntimeEngine 实例来检索 KieSession 或 TaskService 实例。此方法可确保引擎的正确状态根据所选的策略进行管理。
66.2.1. 运行时管理器策略 复制链接链接已复制到粘贴板!
RuntimeManager 类支持以下管理 KIE 会话策略。
- 单例策略
此策略指示运行时管理器维护单一
RuntimeEngine实例(并依次使用单个KieSession和TaskService实例)。对运行时引擎的访问会被同步,因此线程安全,但因同步而出现性能损失。对此策略用于简单用例。
此策略具有以下特征:
- 它的内存占用少,具有运行时引擎的单一实例和任务服务。
- 在设计和使用方面简单而紧凑。
- 由于同步访问,它非常适合流程引擎上低到中等负载。
-
在这个策略中,因为单个
KieSession实例,所有状态对象(如事实)都直接对所有进程实例可见,反之亦然。 -
该策略不是上下文。从单例
RuntimeManager检索RuntimeEngine实例时,您不需要将Context实例考虑在内。通常,您可以将EmptyContext.get()用作上下文,虽然还接受 null 参数。 在这个策略中,运行时管理器会跟踪
KieSession的 ID,以便在RuntimeManager重启后使用相同的会话。ID 做为一个序列化的文件存储在文件系统中,具体取决于环境,可以是以下目录之一:-
jbpm.data.dir系统属性的值 -
jboss.server.data.dir系统属性的值 -
java.io.tmpdir系统属性的值
-
警告Singleton 策略和 EJB Timer 调度程序的组合可能会引发 Hibernate 问题。不要在生产环境中使用这个组合。EJB 计时器调度程序是 KIE 服务器中的默认调度程序。
- 每个请求策略
此策略指示运行时管理器为每个请求提供一个新的
RuntimeEngine实例。在一个事务中对进程引擎执行一个或多个调用被视为一个请求。必须在单一事务中使用同一个
RuntimeEngine实例,以确保状态正确。否则,在下一个调用中无法看到一个调用中的操作。这个策略是无状态的,因为进程状态仅在请求内保留。当请求完成后,
RuntimeEngine实例会被永久销毁。如果使用持久性,与 KIE 会话相关的信息也会从持久性数据库中删除。此策略具有以下特征:
- 它为每一请求提供完全隔离的进程引擎和任务服务操作。
- 它是完全无状态的,因为事实仅存储在请求的持续时间内。
- 它非常适合高负载、无状态进程,在请求之间不能保留事实或计时器。
- 在这个策略中,KIE 会话仅在请求生命周期中可用,并在请求结束时销毁。
-
该策略不是上下文。从每个请求的
RuntimeManager检索RuntimeEngine实例时,您不需要考虑Context实例。通常,您可以将EmptyContext.get()用作上下文,虽然还接受 null 参数。
- 每个进程实例策略
此策略指示
RuntimeManager在 KIE 会话和进程实例之间保持严格的关系。每个KieSession都可用,只要它所属的ProcessInstance才可用。此策略提供了使用流程引擎的高级功能的最灵活方法,如进程实例之间的规则评估和隔离。它可最大化性能并减少同步带来的潜在瓶颈。同时,与请求策略不同,它会将 KIE 会话的数量减少到实际进程实例数,而不是请求总数。
此策略具有以下特征:
- 它为每个进程实例提供隔离。
-
它在
KieSession和ProcessInstance之间有一个严格的关系,以确保它始终为给定进程实例提供相同的KieSession。 -
它将
KieSession与ProcessInstance的生命周期合并,当进程实例完成或中止时,它们都被处理。 - 它可在进程实例范围内维护数据,如事实和计时器。只有进程实例有权访问数据。
-
它引入了一些开销,因为需要查找和加载进程实例的
KieSession。 -
它将验证每个
KieSession的使用,使其不能用于其他进程实例。如果另一个进程实例使用相同的KieSession,则抛出异常。 该策略是上下文,接受以下上下文实例:
-
EmptyContext或 null: 在启动进程实例时使用,因为还没有可用的进程实例 ID -
ProcessInstanceIdContext: 在创建进程实例后使用 -
CorrelationKeyContext: 用作ProcessInstanceIdContext的替代选择,使用自定义(业务)密钥而不是进程实例 ID
-
66.2.2. 运行时管理器的典型用法场景 复制链接链接已复制到粘贴板!
运行时管理器的典型用法场景由以下阶段组成:
在应用程序启动时,完成以下阶段:
-
构建一个
RuntimeManager实例,并在应用程序的整个生命周期内保留它,因为它是 thread-safe,并可同时访问。
-
构建一个
在请求时,完成以下阶段:
-
从
RuntimeManager获取RuntimeEngine,使用正确的上下文实例由您为RuntimeManager类配置的策略决定。 -
从
RuntimeEngine中获取KieSession和TaskService对象。 -
将
KieSession和TaskService对象用于操作,如startProcess或completeTask。 -
完成处理后,使用 Runtime
Manager.dispose方法处理。RuntimeEngine
-
从
在应用程序关闭时,完成以下阶段:
-
关闭
RuntimeManager实例。
-
关闭
当从活跃的 JTA 事务中的 RuntimeEngine 获得 RuntimeEngine 时,您不需要在结束时退出 RuntimeEngine,因为 会自动对事务完成处理 RuntimeManager RuntimeEngine (禁止完成状态:提交或回滚)。
以下示例演示了如何构建 RuntimeManager 实例,并获取 RuntimeEngine 实例(封装了 KieSession 和 TaskService 类):
构建 RuntimeManager 实例,然后获取 RuntimeEngine 和 KieSession
这个示例提供了使用 RuntimeManager 和 RuntimeEngine 类的最简单或最小方法。它具有以下特征:
-
KieSession实例创建在内存中,使用newDefaultInMemoryBuilder构建器。 - 单个进程(作为资产添加)可用于执行。
-
TaskService类通过LocalHTWorkItemHandler接口配置并附加到KieSession实例,以支持进程中的用户任务功能。
66.2.3. 运行时环境配置对象 复制链接链接已复制到粘贴板!
RuntimeManager 类封装了内部进程引擎复杂性,如创建、处理和注册处理程序。
它还提供对流程引擎配置的精细控制。要设置此配置,您必须创建一个 RuntimeEnvironment 对象,然后使用它创建 RuntimeManager 对象。
以下定义显示了 RuntimeEnvironment 接口中可用的方法:
RuntimeEnvironment 接口中的方法
66.2.4. 运行时环境构建程序 复制链接链接已复制到粘贴板!
要创建包含所需数据的 RuntimeEnvironment 实例,请使用 RuntimeEnvironmentBuilder 类。此类提供了一个流畅的 API,用于通过预定义的设置配置 RuntimeEnvironment 实例。
以下定义显示了 RuntimeEnvironmentBuilder 接口中的方法:
RuntimeEnvironmentBuilder 接口中的方法
使用 RuntimeEnvironmentBuilderFactory 类,获取 RuntimeEnvironmentBuilder 的实例。除了空实例没有设置外,您还可以通过运行时管理器的几个预配置的配置选项集合获取构建器。
以下定义显示了 RuntimeEnvironmentBuilderFactory 接口中的方法:
RuntimeEnvironmentBuilderFactory 接口的方法
运行时管理器还提供 TaskService 对象作为 RuntimeEngine 对象的集成组件(配置为与 KIE 会话通信)。如果您使用默认构建器之一,则任务服务的以下配置设置已存在:
-
持久性单元名称设置为
org.jbpm.persistence.jpa(用于进程引擎和任务服务)。 - 人工任务处理程序在 KIE 会话中注册。
- 基于 JPA 的历史日志事件监听程序在 KIE 会话中注册。
-
触发规则任务评估的事件监听程序(
fireAllRules)在 KIE 会话上注册。
66.2.5. 为运行时引擎注册处理程序和监听程序 复制链接链接已复制到粘贴板!
如果您使用运行时管理器 API,则运行时引擎对象代表进程引擎。
要使用自己的处理程序或监听程序扩展运行时引擎,您可以实施 RegisterableItemsonnectionFactory y 接口,然后使用 RuntimeEnvironmentBuilder.registerableItemsFactory() 方法将其包含在运行时环境中。然后,运行时管理器自动为它创建的每个运行时引擎添加处理程序或监听程序。
以下定义显示了 RegisterableItemsFactory 接口中的方法:
RegisterableItemsFactory 接口的方法
进程引擎提供 RegisterableItemsFactory 的默认实现。您可以扩展这些实施来定义自定义处理程序和监听程序。
以下可用的实现可能很有用:
-
org.jbpm.runtime.manager.impl.SimpleRegisterableItemsFactory: 最容易的实施。它没有任何预定义的内容,使用反射来生成基于给定类名称的处理程序和监听程序的实例。 -
org.jbpm.runtime.manager.impl.DefaultRegisterableItemsFactory:简单实施的扩展引入了与默认运行时环境构建器相同的默认值,仍然提供与 Simple 实施相同的功能。 -
org.jbpm.runtime.manager.impl.cdi.InjectableRegisterableItemsFactory:为 CDI 环境量身定制的默认实现的扩展,并提供 CDI 风格方法来使用制作者查找处理程序和监听器。
66.2.5.1. 使用文件注册工作项处理程序 复制链接链接已复制到粘贴板!
您可以通过在 CustomWorkItem.conf 文件中定义文件并将该文件放置到类路径中,注册简单的工作项目处理程序(无状态或依赖于 KieSession 状态)。
流程
-
在类路径的根目录下的
META-INF子目录中创建一个名为drools.session.conf的文件。对于 Web 应用,目录为WEB-INF/classes/META-INF。 在
drools.session.conf文件中添加以下行:drools.workItemHandlers = CustomWorkItemHandlers.conf
drools.workItemHandlers = CustomWorkItemHandlers.confCopy to Clipboard Copied! Toggle word wrap Toggle overflow -
在同一目录中创建一个名为
CustomWorkItemHandlers.conf的文件。 在
CustomWorkItemHandlers.conf文件中,使用 MVEL 风格定义自定义工作项目处理程序,如下例所示:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
结果
您列出的工作项目处理程序是为应用程序创建的任何 KIE 会话注册,无论应用程序使用了运行时管理器 API。
66.2.5.2. 在 CDI 环境中注册处理程序和监听程序 复制链接链接已复制到粘贴板!
如果您的应用使用运行时管理器 API 并在 CDI 环境中运行,则您的类可以实施专用制作者接口,为所有运行时引擎提供自定义工作项目处理程序和事件监听程序。
要创建工作项处理程序,您必须实施 WorkItemHandlerProducer 接口。
WorkItemHandlerProducer 接口的定义
要创建事件监听程序,您必须实现 EventListenerProducer 接口。给事件监听器制作者添加正确的限定符,以指示它所提供的监听程序类型。使用以下注解之一:
-
@processforProcessEventListener -
@agendaforAgendaEventListener -
@WorkingMemoryforWorkingMemoryEventListener
EventListenerProducer 接口的定义
通过在 META-INF 子目录中包含 bean 归档,将您的接口实施打包为 bean 归档。将 bean 归档放置在应用程序类路径上,例如,在 Web 应用的 WEB-INF/lib 中。基于 CDI 的运行时管理器发现软件包,并在它从数据存储中创建或加载的每个 KieSession 中注册工作项目处理程序和事件监听程序。
进程引擎为制作者提供某些参数,以启用有状态和高级操作。例如,处理程序或监听器可以使用参数来发送进程引擎,或当出错时向进程实例发出信号。进程引擎以参数的形式提供以下组件:
-
KieSession -
TaskService -
RuntimeManager
另外,RuntimeManager 类实例的标识符作为参数提供。您可以对标识符应用过滤来决定此 RuntimeManager 实例是否接收处理程序和监听程序。