如何解决Drools 性能评估
我想执行一个有状态/无状态的流口水会话? 假设 Spring Boot 的默认线程池大小。 我应该如何考虑服务器处理能力?
规则很简单:
when
Apple( color == red )
then
System.out.println("hello");
end
规则引擎可以支持的每秒最大调用次数是多少? 我如何得出计算结果?
解决方法
这取决于太多因素,无法具体说“每个 Y 规则需要 X 个资源”。是的,规则 count 是(有点)重要的,但其他事情也很重要。我一直在做的,也推荐你做的是,分配你认为合理的内容,对你认为将是峰值负载的内容进行压力测试——然后将其加倍(或其他一些合理的倍数)。发送并发要求。发送复杂的数据。发送简单数据。发送看起来合法的数据。确保您的日志记录解决方案(如果相关)不会影响您的规则执行。一旦您观察到该行为,您就可以调整您的生产配置。
一般来说,您将通过以下方式查看资源使用情况:
-
工作记忆。当您将对象传递到规则引擎以执行时,这些对象将被序列化然后反序列化。这是堆的主要使用者——您传递给规则的序列化/反序列化对象。请注意,如果您有创建新对象并将它们添加到内存的规则——这些规则也会增加您的堆使用量。
我明确提到了序列化/反序列化,因为您应该确认您的对象是否干净且正确地进行了序列化/反序列化。我曾经参与过一个项目,我们将一个对象传递给 Drools,该对象大小约为 20kb,但序列化后会爆炸到接近 1.2mb。我们无法弄清楚为什么当我们传入如此少的数据时,我们的内存总是会耗尽,但最终我们意识到这不是数据,而是我们使用的结构序列化不好。 -
重新评估和循环。规则执行占用 CPU。这似乎很明显,但有一些特定的 Drools 工作流程会增加他的 CPU 使用率。如果您曾调用
modify
、update
或insert
,这会导致部分或完全重新评估规则。因此,如果您的规则在执行一次时消耗 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 举报,一经查实,本站将立刻删除。