转载

提高 IBM Operational Decision Manager 的性能,第 2 部分: 减少规则执行的资源使用

简介

本教程是一个教程系列的第 2 部分,该系列将指导您配置 IBM ODM 模块、环境和应用程序,以便在 Rule Execution Server 上实现最佳的规则执行性能。第一篇教程 改善 IBM Operational Decision Manager 的性能,第 1 部分:减少规则执行时间 介绍了 IBM ODM 的组件和可缩短规则集执行时间的配置。本教程解决在 Rule Execution Server 上遇到的与资源使用相关的性能问题。

试用 Business Rules 服务

在业务策略变更时,花更少时间来记录和测试。 来自 Bluemix 的 Business Rules 服务 通过保持业务逻辑与应用程序逻辑分析,最大限度地减少了代码更改。免费试用!

除了讨论与特定版本相关的特定行为的时候,本教程适用于 IBM ODM 7.5 及更高版本。教程中所示的配置使用 IBM ODM V8.7,这是本文发表之时的最新版本。请注意,一些配置的默认值在不同版本中不同。请在产品文档中确认您使用的版本的配置。要利用客户修补程序和特性,请确保您已在所使用的版本上安装了最新的修补包。

如果在 z/OS 上使用 IBM ODM,那么除了本系列中建议,还应参阅以下资源:

  • IBM ODM 文档中的 配置 IMS 以在 zRule Execution Server for z/OS 上执行规则
  • IBM ODM 文档中的为 z/OS 开发规则项目
  • IBM ODM 文档中的调整 z/OS 配置
  • IBM ODM 文档中的 改善 COBOL 程序决策表的性能
  • IBM ODM 文档中的 特定于 COBOL 规则子程序的 COBOL 注意事项
  • IBM 红皮书 通过业务规则和事件为 ZEnterprise 实现灵活的决策自动化 中的 17.1 节(性能)

回页首

Rule Execution Server 性能

在 Rule Execution Server 上运行规则时,以下症状是报告最多的性能问题。

  • 较长的规则集执行时间。
  • 规则集调用期间的高内存利用率。
  • 规则集调用期间的高 CPU 利用率。
  • 对托管的透明决策服务的缓慢响应时间。

本教程重点介绍解决以下问题的建议:高内存和 CPU 利用率。系列的第 3 部分解决托管的透明决策服务的缓慢响应时间问题。

对于每种场景,性能可能会受规则跟踪和日志记录的影响。减少规则跟踪和日志可能会有所帮助,如第 1 篇教程中的 减少实际规则集执行时间的推荐配置 节中所述。

回页首

减少高内存利用率的建议

组织面临的性能挑战之一是执行规则时内存利用率很高。症状包括高内存使用率和 OutOfMemoryErrors

如果遇到高内存利用率,从以下位置收集诊断信息会有所帮助:

  • 定期的间隔后生成的堆转储。
  • 来自 Rule Execution Server 控制台的规则集缓存信息(执行单元转储)。要获取有关执行单元内存使用情况的信息,应将 rulesetUsageMonitorEnabled 执行单元 (XU) 属性设置为 true 。请参阅 IBM ODM 文档中的 获取执行单元 (XU) 内存使用信息 。

分析堆使用情况,以查明在何处使用了堆,例如在规则集解析或规则集监视期间。

可通过更改规则集设计、服务器配置和应用程序设计来减少规则集执行期间使用的内存,如图 1 所示。

图 1. 减少内存使用的建议

提高 IBM Operational Decision Manager 的性能,第 2 部分: 减少规则执行的资源使用

规则集设计更改

要减少规则集执行期间的内存使用,可应用第 1 篇教程中的规则集设计更改 节中减少规则集解析时间的建议。此外,执行一下规则集设计更改,如图 2 所示。

图 2. 减少内存使用的规则集设计

提高 IBM Operational Decision Manager 的性能,第 2 部分: 减少规则执行的资源使用
  1. 优化规则工件设计。
    • 在经典规则引擎中,可通过限制同一个工作流中使用的不同引擎执行模式(或算法)来节省内存,最好在所有任务上使用同一种执行模式。使用 RetePlus 算法时,经典规则引擎管理一个规则集的所有规则,即使规则任务中只有一个规则集在运行。可在 Rule Designer 中为规则任务设置默认执行模式,单击 Window > Preferences > Rule Designer > Ruleflow 即可。
    • 如果使用 RetePlus 引擎执行模式,可考虑使用动态字节码生成,因为这也会减少运行时的垃圾收集器活动。
    • 如果使用 Sequential 引擎执行模式和经典规则引擎,可通过以下一种方式指定运行时规则选择来减少规则引擎的内存使用:
      • select 关键字(使用 静态 BAL 规则任务属性 指定),
      • dynamicselect 关键字(使用 动态 BAL 规则任务属性 指定),后跟一个规则域。

      使用 dynamicselect 关键字而不选择规则域,可能是永久生成 (PermGen) 空间不足的原因之一,因为然后会为每次执行生成字节码。如果对一个运行 Rule Execution Server 的进程运行 jmap -permstat 命令,可以发现占用 PermGen 空间的不活动类加载器,比如 IlrBinaryClassLoaderIlxJITClassLoader 。这些类加载器可在解析规则集时创建,尤其是对于具有 Sequential 和 Fastpath 执行模式的规则任务。类加载器用于将字节码加载到 Java® 虚拟机 (JVM) 中,字节码是在运行时为执行规则任务而生成的。如果使用 dynamicselect 关键字而不选择规则域,可能为规则任务的每次执行生成一个类加载器。

      使用 dynamicselect 关键字和一个规则域,可减少 Rule Execution Server 所需要的使用 PermGen 空间的类加载器数量。它也可确保字节码仅为该规则任务生成一次。对这些类加载器的引用会在从 Rule Execution Server 规则集缓存中删除规则集后丢弃,JVM 可以自由地收回该空间。但是,JVM 的实现确定了不活动的类加载器在 PermGen 中保留的时间。请参阅 dW Answers 上的 Rule Execution Server 和 JVM 的 PermGen 空间中的不活动类加载器 。

  2. 更改规则集版本部署行为。 减少当前部署的活动规则集版本数量。

    如果仅部署了一个活动版本,可将 ruleset.maxIdleTime 规则集属性设置为 0 并设置部署策略来更换版本,以便一次只有一个活动的规则集版本(参见 IBM ODM 文档中的版本策略选项)。此值可确保规则集不会从缓存中删除,除了在重新部署(和重新解析)它时。如果部署了多个版本且 ruleset.maxIdleTime=0 ,那么即使所有请求都是针对最新版本的,最新版本以前的版本也会无限期地缓存在内存中。因此,在一个规则集的多个版本上使用 ruleset.maxIdleTime=0 ,可导致在没有任何针对旧版本的执行请求以后很久,旧版本仍保留在内存中。因此,不推荐使用此方法。在此场景中,可将 ruleset.maxIdleTime 设置为大于 0 的值,以确保规则集版本会在超出最大空闲时间后从缓存中清除,进而释放内存。

    如果将 ruleset.maxIdleTime 设置为 >=0,您还应确保 rulesetUsageMonitorEnabled 属性设置为 true 。请参阅 IBM ODM 文档中的 管理规则集的最大空闲时间 。

服务器配置更改

按照以下指南配置服务器:

  1. 针对您的需求 选择合适的拓扑结构 。要最大限度减少内存使用,推荐使用以下拓扑结构(来自 InterConnect 2015 演示 设计和开发 IBM ODM 应用程序来优化性能 中的 “拓扑结构选择” 节):
    • Java Platform, Standard Edition (Java SE)、带决策引擎的 Rule Execution Server。
    • Liberty V8.5.5.3 上带决策引擎的 Rule Execution Server,如果您使用的是 IBM ODM V8.7 或更高版本。通过仅提供应用程序需要的服务器特性,Liberty 概要文件仅使用很小的空间。Liberty 服务器可托管 Rule Execution Server 控制台、透明的决策服务,以及测试和模拟工作。请参阅 IBM ODM 文档中的 在 Liberty 概要文件上配置 Rule Execution Server 。

      可在 IBM ODM 文档中的部署架构 中进一步了解如何选择正确的部署架构。

  2. 调整 Rule Execution Server XU 连接池 ,如图 3 所示。

    图 3. 减少内存使用的 XU 连接池配置

    提高 IBM Operational Decision Manager 的性能,第 2 部分: 减少规则执行的资源使用

    执行单元维护着一个连接池。每个连接引用一个一解析的规则集实例,这个实例可在调用时立即执行。如果使用 Java Platform, Enterprise Edition (Java EE),可以通过应用服务器配置连接池大小;或者如果使用 Java SE,可在 ra.xml 文件中配置。

    如果遇到内存问题,可减小连接池大小。配置池大小来平衡内存资源限制与规则集执行性能需求。正如第一篇教程 中 “减少规则集解析时间的建议” 下的 “执行单元配置” 节中所讨论的,连接池应足够大,以便满足以下条件:

    • 有连接可用来支持所有规则集上的并发执行,而不会导致请求更少的规则集被驱逐。
    • 不对较少使用的规则集调用规则集解析。

      要平衡此需求与有限的内存资源,可考虑基于规则集的调用和更新频率来为它们分配不同的连接池,如图 3 所示。可为以下类型的规则集配置不同的连接池:

      • 频繁调用或更新的规则集。为此池设置较小的超时值,以便旧规则集会更快从缓存中清除并释放内存资源。请注意,设置较小的超时可以更快地清除旧规则集,即使它们被频繁使用。
      • 很少调用或更新的规则集。为此池设置较大的超时值,以避免在从缓存中清除规则集后调用它所导致的较长的解析时间。
  3. 禁用规则集使用数据的监视。 如果发现 IlrRulesetUsageInformationMonitorImpl 类使用了大量内存,可考虑将执行单元 rulesetUsageMonitorEnabled 属性设置为 false ,禁用对执行单元的规则集使用数据的监视。这将释放与 IlrRulesetUsageInformationMonitorImpl 类关联的内存。请注意,这么做会禁用对执行单元内存使用情况的监视,以及抑制 ruleset.maxIdleTime 规则集属性的值的效果。
  4. 减少缓存中的已编译归档文件。 为决策引擎使用规则集归档文件( .dsar 文件)时,通过 Rule Designer 会尽可能多创建 .dsar 文件,以便在其中生成字节码。

    从 Decision Center 生成的任何 .dsar 文件都不包含字节码,所以必须在运行时生成字节码。将 compiledArchivesCacheProperties XU 属性设置为 true ,配置已编译的归档文件缓存来限制字节码仅在规则集第一次执行时生成。在后续执行过程中,会从基于文件的缓存中读取生成的字节码。

    要释放内存,可通过将 compiledArchivesCacheProperties.maxSize XU 属性的值调节为小于其默认值 10 ,减少缓存中的已编译归档文件的最大数量。

  5. 依据以下指南 调整内存设置

    • 如果可能,向系统添加更多内存。
    • 分配足够的 JVM 堆大小(64 位 JVM),确保您使用了最新的受支持 JVM 和更新。您可使用 -Xms-Xmx 开关指定初始和最大大小,覆盖默认堆大小。
    • 如果获得 java.lang.OutOfMemoryError:PermGen space 错误,可使用 -XX:MaxPermSize JVM 开关增加永久生成堆。如果应用程序使用动态代码生成,例如如果使用 JavaServer Pages (JSPs) 或生成的字节码来支持规则集,则应增加 GermGen 堆空间。要确定最优的 MaxPermSize 值,可使用实际的负载设置来对应用程序执行负载测试,包括热部署,并监视堆和 PermGen 的使用。
    • 解析可触发垃圾收集来释放内存。收集详细的垃圾收集统计信息,使用 -verbose:gc 关联解析持续时间与堆清理。相应地调优垃圾收集器和内存大小: -Xms3064M -Xmx3064M -verbose:gc -d64 -XX:MaxPermSize=256m
    • 使用 -Xgcpolicy:gencon 选项帮助最小化任何垃圾收集暂停所花的时间。在 IBM JVM 上, gencongarbage 收集器策略在中小型应用程序上拥有良好的结果。
    • 如果使用 Sequential 执行模式在,则使用以下 JVM 参数: -Xjit:{ilog/rules/engine/sequential/generated/*}(disableInlining)

    能改善性能的 JVM 参数可能类似于下面这个示例:

    -Xgcpolicy:gencon -Xmn2048M -Xgcthreads4 -Xcompressedrefs                 -Xjit:{ilog/rules/engine/sequential/generated/*}(disableInlining)                 -Xmx4096m -Xms4096m

    -Xgcthreads4 开关表示垃圾收集线程的数量,包括应用程序线程,而且默认比 CPU 数量少一个。

应用程序设计更改

在客户端执行以下更改,只要它们适用于您的环境:

  1. 不要一次部署或解析所有规则集。限定多个规则应用程序或规则集的热部署时间,以便在任何给定时刻仅解析一个规则集。规则集解析会使用内存,一些规则集可在解析完成后收回,所以等待一次规则集解析完成后再部署另一个规则集,有助于保持较低的内存占用。
  2. 设计您的客户端应用程序以配置一次规则集热加载,如第 1 篇教程中的 减少规则集解析时间的建议 中的 “应用程序设计” 节。分散加载时间以减少内存使用。也可将应用程序设计为运行 2 个或更多线程来解析多个规则集。
  3. 如果使用规则引擎 API 调用规则,可创建多个使用同一个规则集的引擎,以减少内存使用。
    • 如果使用经典规则引擎,可创建多个并行运行的引擎来使用同一个规则集。请参阅 IBM ODM 文档中的 将同一个规则集用于多个规则引擎 。此更改可能对多线程执行性能具有细微的影响。
    • 如果使用决策引擎,可从同一个定义创建多个引擎并并发地使用它们。请参阅 IBM ODM 文档中的 将同一个定义用于多个决策引擎 。此更改不会降低性能。
  4. 减少业务对象模型 (BOM) 输入参数对象的数量和大小。减少 XML 对象大小,可在将 XML 输入参数发送给托管的透明决策服务时避免 OutOfMemoryErrors 。可使用Decision Warehouse 检查输入参数的内容。对于 XML 数据,可使用来自 XML 库的工具来测量 XML 对象的大小。对于大型 XML 对象(XML 解析的成本占整体处理成的很高比例),可执行 XPATH 查询来提取需要的值,然后将该信息传递给规则集。
  5. 如果使用 XML XOM 和 IlrXmlDefaultDataDriver() 类,可调用 end() 方法来恰当地处置分配的内存。
  6. 在 Java SE 实现中,可在多个客户端中分享一个 IlrJ2SESessionFactory 独体对象。例如,保留会议工厂的一个静态引用,或者实现一种独体设计模式来保存会话工厂的共享引用。如果在每次执行时重新创建会话工厂,每次都会重新创建一个 XU 池,而且不支持在客户端之间共享引擎和规则集资源。因此,这会增加内存使用。

回页首

减少高 CPU 利用率的建议

回顾一下,目前为止,本教程讨论了减少内存使用率的建议。同样地,在执行规则时,系统可能具有很高的 CPU 利用率,或许甚至发生 CPU 饥饿。线程转储可能表明大量线程在等待连接。

如果发生高 CPU 利用率,从以下来源收集诊断信息会有所帮助:

  • 服务器日志,包括 trace.log 。要诊断问题,可将跟踪级别设置为 *=info:com.ibm.rules.*=all 以获得最多信息。
  • 线程转储。

高 CPU 利用率可能源于大量的并发请求。分析有多少平法客户端在同时执行规则集,执行频率是多少。另外分析有多少不同的规则集在执行。例如,多个线程可能同时执行规则集解析,这非常消耗资源。

可通过更改规则集设计、服务器配置和应用程序设计来减少 CPU 利用率,图 4 进行了总结。

图 4. 减少 CPU 利用率的建议

提高 IBM Operational Decision Manager 的性能,第 2 部分: 减少规则执行的资源使用

规则集设计更改

如果在 IlrRulesetProvider.getRuleset 方法上看到挂起的线程,可将 ruleset.shareable 属性设置为 false ,以便排除任何与跨多个执行线程共享同一个规则集对象相关的潜在同步或争用问题。但是,此更改可能对内存占用和规则集解析产生重要影响,因为并发执行的线程可能请求规则集的多个已解析和已缓存的表示。

服务器配置更改

按照以下指南配置服务器:

  1. 增加 Rule Execution Server XU 连接池大小,以避免重新解析从连接池驱逐出的规则集期间的高 CPU 使用率。增加池大小,以便很少达到 JVM 最大堆大小,避免高 CPU 使用率阶段,或者检测到大量线程在等待连接。请参阅 Rule Execution Server 引擎池大小调节 支持文档和 dW Answers 上的 监视执行单元连接池大小 答案。另请参阅第 1 篇教程中的减少规则集解析时间 中的 “执行单元配置更改” 节。确保 XU 的连接池大小是在节点级别设置的,而不是在集群级别。

    考虑利用特定于应用服务器的池属性。例如,如果在 WebSphere Application Server 中看到以下错误: J2CA0045E:Connection not available while invoking method createOrWaitForConnection for resource jdbc/resdatasource ,可对连接池设置执行以下更改:

    • 增加 Maximum connections ,以指定可在这个池中创建的物理连接的最大数量。
    • Purge policy 更改为 Entire Pool ,以确保当发成一次连接异常时,会刷新整个池。
    • 增加 Unused timeoutAged timeout ,以确保旧连接被定期刷新,避免过时的连接。请参阅 IBM WebSphere Application Server 中的连接池设置,了解减少连接池大小的详细信息。
  2. 增加 CPU 核心数量,去报工作负载均匀分散在节点之间,以考虑到 CPU 数量。
  3. 通过部署在生产环境中的一个集群中,配置 Rule Execution Server 来实现高可用性和可伸缩性。请参阅 IBM ODM 文档中的集群配置和拓扑结构 和 将服务器加入集群来实现高可用性和可伸缩性 。另外,如果有许多 Decision Center 用户在执行测试过程,则将 Decision Validation Services 加入到测试环境中的集群中。请参阅将 Decision Validation Services 加入集群 支持文档。
  4. 使用特定于应用服务器的设置来限制并发线程数量。举例而言,如果 Rule Execution Server 部署在 WebSphere Application Server 上,可考虑对应用服务器设置执行以下更改:
    • 减少 Web Container thread pool maximum size ,以限制可在任何给定时刻主动执行传入的 HTTP 请求的线程数量。
    • 减少 com.ibm.websphere.ejbcontainer.poolSize ,以限制指定 bean 类型(无状态、消息驱动和条目 bean)的池大小。
    • Maximum concurrent MDB invocations per endpoint (指定消息并发传送到的最大端点数量)设置为获得消息的并发线程的最大数量。

应用程序设计更改

如果适用,依据以下指南来设计您的客户端应用程序:

  • 在单独的服务器或机器上运行应用程序。
  • 减少同时从客户端传来的规则请求,比如消息驱动的 bean (MDB) 或r Enterprise JavaBean (EJB)。
  • 使用单个有状态规则会话来执行批处理,为每个批次使用一个引擎,而不是每次请求一个新引擎。
  • 根据前面的建议,在 Java SE 实现中,可在多个客户端中分享一个 IlrJ2SESessionFactory 独体对象。例如,保留会议工厂的一个静态引用,或者实现一种独体设计模式来保存会话工厂的共享引用。如果在每次执行时重新创建会话工厂,每次都会重新创建一个 XU 池,而且不支持在客户端之间共享引擎和规则集资源。因此,CPU 使用率会增加。

有关性能改进的更多指南,请参阅以下资源:

  • IBM ODM 文档 概述:哪些因素会影响 Decision Server 应用程序的性能
  • InterConnect 2015 演示 设计和开发 IBM ODM 应用程序来优化性能
  • IBM Operational Decision Management V8.0 性能调优指南 中的第 6、7 和 8 章
  • 性能:如何调优 IBM ODM 解决方案 演示中的 调优 Decision Server 规则 节。

回页首

结束语

本教程介绍了配置 IBM ODM 和规则和客户端应用程序,以减少规则执行期间的资源使用的推荐实践。可选择最适合您需求的设置,并相应地自定义您的应用程序和环境。本系列的下一篇教程 介绍如何减少托管透明决策服务的响应时间。

整合这些建议之前,请确保您阅读了这个改善 IBM ODM 的性能 系列的第 1 部分。

致谢

感谢 Franck Delporte、Alain Robert 和 Pierre Berlandier 对本教程的评审和贡献。另外感谢 IBM ODM 技术解决团队 - 包括 2 级支持、3 级支持和研发团队 - 以及参考文档的作者。

正文到此结束
Loading...