首页 > 解决方案 > 如何在 Drools 中跟踪多个心跳?

问题描述

我有一个场景,我从多个来源接收心跳,并且需要使用 Drools 来跟踪它们。我知道我会提前处理多少个来源,并且可以随时引入新的来源(可能是数百个)。心跳对象包含指示心跳源 (a String) 和来自该源的心跳应该到达的速率 (an int,以秒为单位) 的属性。对于给定的源,心跳率也可以改变。我需要跟踪所有已知的来源,它们的心跳率,处理新的来源,并在任何给定的心跳过期和/或心跳没有按预期进入时执行操作。

我知道文档中的心跳语法示例,但据我了解,这不支持变量(即我不能在after语句中使用变量)。我一直在研究时间运算符入口点@timestamp和标签,@expires以及其他可能相关的特性,但还没有找到解决方案。

我知道 Drools 可以做很多事情,也许我不太从“规则引擎”的思维方式中看到事情,但我真的不知道如何做到这一点。如果有人可以提供一些见解,将不胜感激。谢谢你。

标签: drools

解决方案


我认为您误解的关键部分是文档中的“心跳”不是 Drools 内置的——这是他们用来说明简单用例的示例。代表你的心跳的类可以是你定义的,所以你的应用程序的心跳可以根据你的需要改变它们的模型。

这意味着您可以将心跳模型定义为您想要的任何东西。解决您的问题的一种简单方法是在名为的类中包含一个字段,该字段source指示您的心跳来自何处。然后,您可以对规则条件添加限制,以将规则限制为特定源。

因此,例如:

class MyHeartbeat {
  private String source;
  // other fields as needed/appropriate
  // getters and setters
}

然后你可以编写如下规则:

import com.example.MyHeartbeat

declare MyHeartbeat
  @role( event )
end

rule "Trigger for event from source A"
when
  $h: MyHeartbeat(source == "A") from entry-point "MonitoringStream"
  not(MyHeartbeat(this != $h, this after[0s,10s] $h, source == "A") from entry-point "MonitoringStream")
then
  // Do something for this Event from source A
end

rule "Trigger for event from source B, C or D"
when
  $h: MyHeartbeat(source in ("B", "C", "D")) from entry-point "MonitoringStream"
  not(MyHeartbeat(this != $h, this after[0s,10s] $h, source in ("B", "C", "D")) from entry-point "MonitoringStream")
then
  // Do something for event from source B/C/D
end

您会注意到,除了使用我定义的心跳类之外,此规则几乎是文档中的复制粘贴。

如果您有一组离散的来源,您可以采用多个入口点的路线——例如,每个来源一个。但是正如您所提到的,您可能有任意数量的它们,这不会使定义离散入口点成为您的有效工作流程,因为这将需要大量开销和维护。


推荐阅读