bal*_*azs 5 java multithreading web-services drools
我正在使用Drools 5.6.0,我已准备好升级到6.0,因此这个问题与两个版本都相关.
我已经搜索了很多关于在多线程环境中使用Drools的内容,我仍然不确定如何继续.在下面的场景中,我试图找到一种方法,将使用大量静态事实预先初始化的单例StatefulKnowledgeSession用作Web服务的业务逻辑.
我想知道下面进一步描述的场景是否有最佳实践.
我在服务器启动时创建一个StatefulKnowlegdeSession单例
在初始化时,我将超过100.000个事实插入到StatefulKnowlegdeSession中.我把这些称为" 静态事实 ",因为它们不会被规则修改.静态事实更像是一组大查找表.
现在,规则引擎被放入Web服务(Tomcat)中.Web服务接收将插入到KnowledgeSession中的Request对象.在fireAllRules()之后,我希望KnowledgeSession计算一个输出对象,该输出对象将作为Web服务响应返回.
响应的计算使用静态事实.规则创建了许多临时对象,这些对象使用insertLogical()插入到工作内存中.这样可以确保在Web服务调用结束时收回原始Request对象后,将从工作内存中删除所有垃圾.
现在的问题是我将如何在多线程服务器中完成这项工作?
我想尽可能只使用一个StatefulKnowledgeSession实例(单例),因为静态事实是BIG,它可能成为内存问题.
我不能使用在每个Web服务调用开始时新创建的StatelessKnowledgeSessions,因为插入所有静态事实将花费太长时间.
我知道StatefulKnowlegdeSession不是线程安全的.此外,不再支持分区选项.
但是,可以从不同的线程使用不同的WorkingMemoryEntryPoints/EntryPoints.我可以使用EntryPoints 池,每个Web服务调用将使用池中的一个实例来插入Web服务请求.
这也意味着我需要使用一个特定的EntryPoint,或者至少第一个匹配Web服务请求对象的规则,将每个规则(?)相乘:
rule “entry rule for WORKER-1” // rule to be duplicated for entry points WORKER-2, WORKER-3,...
when
$req : Request () from entry-point “WORKER-1”
$stat : StaticFact( attr = $req.getAttr() )
then
insertLogical( new SomeTemporaryStuff ( $req ) );
end
rule “subsequent rule”
when
$tmp : SomeTemporaryStuff()
then
...go on with the calculation and create a Response at some point...
end
Run Code Online (Sandbox Code Playgroud)
后续规则在工作内存中创建临时对象,此时如果我用几十个并发请求轰炸引擎,我真的害怕弄乱一些东西.
我不会使用多个入口点。将请求排队到运行会话的线程。如果您想利用多核,请运行多个服务或服务线程。
对于 100k 事实,请仔细检查其字段的表示方式。String.intern() 可能可以节省大量成本。其他对象可以 - 因为它都是静态的 - 被共享。通常,在这种情况下,元素构建期间的一些额外开销在以后是有益的,例如,更少的 GC 开销。
(否则,这是一个非常好的总结,几乎是运行此场景的“指南”。+1