Drools 性能评估

如何解决Drools 性能评估

我想执行一个有状态/无状态的流口水会话? 假设 Spring Boot 的认线程池大小。 我应该如何考虑服务器处理能力?

规则很简单:

when
 Apple( color == red )
then
 System.out.println("hello");
end

规则引擎可以支持的每秒最大调用次数是多少? 我如何得出计算结果?

解决方法

这取决于太多因素,无法具体说“每个 Y 规则需要 X 个资源”。是的,规则 count 是(有点)重要的,但其他事情也很重要。我一直在做的,也推荐你做的是,分配你认为合理的内容,对你认为将是峰值负载的内容进行压力测试——然后将其加倍(或其他一些合理的倍数)。发送并发要求。发送复杂的数据。发送简单数据。发送看起来合法的数据。确保您的日志记录解决方案(如果相关)不会影响您的规则执行。一旦您观察到该行为,您就可以调整您的生产配置。

一般来说,您将通过以下方式查看资源使用情况:

  1. 工作记忆。当您将对象传递到规则引擎以执行时,这些对象将被序列化然后反序列化。这是堆的主要使用者——您传递给规则的序列化/反序列化对象。请注意,如果您有创建新对象并将它们添加到内存的规则——这些规则也会增加您的堆使用量。

    我明确提到了序列化/反序列化,因为您应该确认您的对象是否干净且正确地进行了序列化/反序列化。我曾经参与过一个项目,我们将一个对象传递给 Drools,该对象大小约为 20kb,但序列化后会爆炸到接近 1.2mb。我们无法弄清楚为什么当我们传入如此少的数据时,我们的内存总是会耗尽,但最终我们意识到这不是数据,而是我们使用的结构序列化不好。

  2. 重新评估和循环。规则执行占用 CPU。这似乎很明显,但有一些特定的 Drools 工作流程会增加他的 CPU 使用率。如果您曾调用 modifyupdateinsert,这会导致部分或完全重新评估规则。因此,如果您的规则在执行一次时消耗 X 数量的 CPU,但有包含这些特定调用的规则,那么 X 就不是必要的,因为一次执行可能会产生多个其他执行。

    记住这一点很重要,因为 CPU 是规则执行中无限循环的主要指标之一——与死线程一样。如果您看到 CPU 突然出现峰值并且它被固定在那里(并且该线程变得无响应),这表明您的规则可能以输入对象刚刚触发无限循环的方式设计 - 例如。规则 A 触发并更新数据,以便规则 B 触发并更新数据,以便规则 A 触发,依此类推。

    另一方面,如果您定期看到 CPU 峰值回落,这表示您的规则传递复杂数据的次数,因此规则引擎需要大量“努力”来进行计算。输入可能会触发大量规则,或进行大量更新/修改。

    如果您发现规则“慢”,则可能是它们没有足够的 CPU。

这些是对资源的基本持续使用。也就是说,当您拥有一台服务器时,规则已加载,您正在处理请求并将它们传入/传出规则,这通常是您将资源消耗归因于的地方。

然而,重要的是要考虑到 Drools 执行的某些框架相关任务的一次性*命中。

  • 读取和编译规则通常会在从文件系统读取时产生 I/O,或者在远程检索规则时需要考虑网络延迟。规则被读入内存(消耗堆),然后进行处理、验证和编译(消耗 CPU)。
  • 内存中的规则会消耗少量的堆。它们已编译,因此它们消耗的内容将少于解析它们的文本,但它仍然是消耗量。

我曾经维护一个具有 48,000 条规则(大概)的微系统,每秒处理大约 15 个请求,分配使用 16 GB 内存和 4 GB CPU。这些规则永远不会改变工作内存中的数据——这是一个简单的传递。然而,在启动时加载这些规则确实需要大约 10 分钟。 (我会注意到,虽然这是一个 Spring 应用程序,但它是 Spring 2。对我来说没有引导。:( ...)

相反,我有...不幸的是,我也在处理一个有大约 1000 条规则的应用程序的整体。这个应用程序的怪物占据了超过 120 GB 的堆和(我最后一次参与)大约 64 GB 的 CPU。这些规则非常古老(10 年左右)并且不断调用 update(从顶部重新评估所有内容;这相当于使用工作内存中的更新信息再次调用规则......替代方案是 insert 这只是部分重新评估。)这些规则还传递了复杂数据结构中的大量数据(其中大部分是不必要的)。有时,此应用程序会消耗其大部分或全部资源,并且由于无法处理负载而速度减慢至几乎无响应。有时我被要求识别由“更新”调用引起的循环规则。

基本上我想说的是,所需的资源取决于您的应用程序的特性和规则本身的实现。确定适当分配的最佳方法是执行压力测试以确定您的初始应用程序,然后进行监控。密切关注您的交易量——随着您的增长和拥有更多客户或正在处理更多请求,您需要增加分配或重新进行压力测试,以确保您始终有足够的资源来应对高峰,然后再进行一些.

如果您提倡良好的规则设计(尽量减少对更新的调用等)并确保仅将数据传递到实际需要的规则中,您通常可以以线性方式随负载扩展资源消耗缓坡。不幸的是,由于变量太多,因此说“每个 Y 规则的 X 资源”实际上是不可能的事情之一。


* -- 我说加载规则之类的事情是“一次”命中,但实际上是每次加载一次。如果您在应用程序启动时加载一次规则,那将是一次成功。但是,如果您在规则更改后或定期或其他情况下重新加载规则,则您必须在这些时间很好地考虑到这一点。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?