Drools 性能评估

Drools performance estimation

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

规则很简单:

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

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

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

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

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

    我明确提到了 serialization/deserialization,因为您应该确认您的对象干净且正确地执行 serialize/deserialize。我曾经在一个项目中工作过,我们有一个对象要传递到 Drools 中,该对象大小约为 20kb,但在序列化后爆炸到接近 1.2mb。当我们传入这么少的数据时,我们无法弄清楚为什么 运行ning 内存不足,但最终我们意识到它不是数据,而是 结构 我们使用的序列化很差。

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

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

    另一方面,如果您定期看到 CPU 回落,这表明您的规则传递复杂数据的时间使得规则引擎需要大量“努力”来进行计算。输入可能会触发大量规则,或执行大量 updates/modifications。

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

这些是资源的基本持续使用。也就是说,当你有一个服务器时,规则被加载,你正在服务请求并传递它们 in/out 规则,这通常是你将资源消耗归因于的地方。

然而,考虑到 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 这只是部分重新评估。)这些规则还在复杂的数据结构中传递了大量数据(其中大部分是不必要的)。有时此应用程序会消耗其大部分或全部资源,并且由于无法处理负载而减慢到几乎没有响应。有几次我被叫来识别由 'update' 调用引起的循环规则。

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

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


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