第 22 章 与 DRL 相关的性能调优注意事项
以下关键概念或建议做法可帮助您优化 DRL 规则和决策引擎性能。这些概念在本章节中进行了概述,在适用的情况下,会详细介绍相关文档。本节将在 Red Hat Process Automation Manager 的新版本时扩展或更改。
- 定义从左到右侧的模式约束的属性和值
在 DRL 模式限制中,确保事实属性名称位于运算符的左侧,并且值(续或变量)位于右侧。属性名称必须始终是索引中的键,而不是值。例如,写入
Person( firstName == "John" )
而不是Person(John" == firstName)
。定义约束属性和值从右到左可隐藏决策引擎性能。有关 DRL 模式和约束的详情,请参考 第 16.8 节 “DRL 中的规则条件(WHEN)”。
- 在可能的情况下,使用等于运算符以外的其他 Operator 类型
-
虽然决策引擎支持许多可用于定义业务逻辑的 DRL 操作器类型,但同样性运算符
==
被决策引擎最常评估。无论何时,都可使用此运算符而非其他 Operator 类型。例如,其模式Person(firstName == "John")
的评估比Person(firstName != "OtherName")
更高效。在某些情况下,只使用相等的运算符可能并不现实,因此请考虑您的所有业务逻辑需要以及 DRL 操作符的选项。 - 首先列出限制性最严格的规则条件
对于具有多个条件的规则,请列出大多数限制中的条件,以便决策引擎能够在不满足更严格的条件时避免评估整个条件集合。
例如,以下条件是行行书规则的一部分,适用于预订机班和热线的差旅者。在此情景中,客户很少会用航班来享受此折扣的热线,因此热线条件很少满足且很少执行该规则。因此,第一个条件排序更为有效,因为它可防止决策引擎频繁评估动态条件,并在不满足 hotel 条件时不必要的地评估。
首选条件顺序: hotel 和 flight
when $h:hotel() // Rarely booked $f:flight()
效率低:flight 和 hotel
when $f:flight() $h:hotel() // Rarely booked
有关 DRL 模式和约束的详情,请参考 第 16.8 节 “DRL 中的规则条件(WHEN)”。
- 避免过度使用子句来迭代大型对象集合
避免使用 DRL 规则中的
from
condition 元素来迭代大量对象集合,如下例所示:带有
from
clause 的条件示例when $c: Company() $e : Employee ( salary > 100000.00) from $c.employees
在这种情况下,当规则条件被评估并减少规则评估时,决策引擎会迭代大型图形。
另外,除了添加带有大量图表的对象,而是直接将集合添加到 KIE 会话,然后在状况中加入集合,如下例所示:
没有
from
clause 的条件示例when $c: Company(); Employee (salary > 100000.00, company == $c)
在这个示例中,决策引擎只迭代列表一次,并且可以更有效地评估规则。
有关
from
element 或其他 DRL 条件元素的更多信息,请参阅 第 16.8.7 节 “DRL(关键字)中支持的规则条件元素”。- 在用于调试日志的规则中使用决策引擎事件监听程序而不是
system.out.println
语句 您可以在用于调试
日志和控制台输出的规则操作中使用 system.out.println
语句,但对许多规则执行这一操作可能会妨碍规则评估。作为更有效的替代方案,请尽可能使用内置的决策引擎事件监听程序。如果这些监听器无法满足您的要求,请使用决策引擎支持的系统日志实用程序,如 Logback、Apache Commons Logging 或 Apache Log4j。有关支持的决策引擎事件监听程序和日志记录工具的更多信息,请参阅 Red Hat Process Automation Manager 中的决策引擎。
- 使用
drools-metric
模块识别规则中的障碍 您可以使用
drools-metric
模块来标识较慢的规则,特别是处理许多规则时。drools-metric
模块还可协助分析决策引擎性能。请注意,drools-metric
模块不用于生产环境。但是,您可以在测试环境中执行分析。要使用
drools-metric
分析决策引擎性能,首先将drools-metric
添加到项目依赖项中:drools-metric
的项目依赖项示例<dependency> <groupId>org.drools</groupId> <artifactId>drools-metric</artifactId> </dependency>
如果要使用
drools-metric
启用 trace 日志记录,请为org.drools.metric.util.MetricLogUtils
配置日志记录器,如下例所示:logback.xml 配置文件示例
<configuration> <logger name="org.drools.metric.util.MetricLogUtils" level="trace"/> ... <configuration>
或者,您可以使用
drools-metric
使用 Micrometer 来公开数据。要公开数据,请启用您选择的 Micrometer registry,如下例所示:Micrometer 的项目依赖项示例
<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-jmx</artifactId> <!-- Discover more registries at micrometer.io. --> </dependency>
Micrometer 的 Java 代码示例
Metrics.addRegitry(new JmxMeterRegistry(s -> null, Clock.SYSTEM));
无论您是使用日志记录还是 Micrometer,您都需要通过将系统属性
drools.metric.logger.enabled
设置为true
来启用MetricLogUtils
。另外,您可以通过设置drools.metric.logger.threshold
系统属性来更改指标报告的微秒阈值。注意仅报告超过阈值的节点执行。默认值为
500
。将
drools-metric
配置为使用日志记录后,规则执行会生成日志,如下例所示:规则执行输出示例
TRACE [JoinNode(6) - [ClassObjectType class=com.sample.Order]], evalCount:1000, elapsedMicro:5962 TRACE [JoinNode(7) - [ClassObjectType class=com.sample.Order]], evalCount:100000, elapsedMicro:95553 TRACE [ AccumulateNode(8) ], evalCount:4999500, elapsedMicro:2172836 TRACE [EvalConditionNode(9)]: cond=com.sample.Rule_Collect_expensive_orders_combination930932360Eval1Invoker@ee2a6922], evalCount:49500, elapsedMicro:18787
这个示例包括以下关键参数:
-
evalCount
是节点执行期间插入的事实的约束评估数量。当evalCount
与 Micrometer 搭配使用时,包含数据的计数器名为org.drools.metric.evaluation.count
。 -
elapsedMicro
是节点在微秒中所经过的时间。当elapsedMicro
与 Micrometer 一起使用时,查找名为org.drools.metric.elapsed.time
的计时器。
如果您发现了一个未完成的
evalCount
或elapsedMicro
日志,请将节点名称与ReteDumper.dumpAssociatedRulesRete()
输出相关联,以识别与节点关联的规则。ReteDumper 用法示例
ReteDumper.dumpAssociatedRulesRete(kbase);
ReteDumper 输出示例
[ AccumulateNode(8) ] : [Collect expensive orders combination] ...
-