Drools 重用 StatefulKnowledgeSession?
我遇到一个问题,创建新的 drools StatefulKnowledgeSession 实例会占用 CPU 资源。有一个旧的 nabble 链接讨论它
I've got a problem where creating new drools StatefulKnowledgeSession instances is CPU intensive. There's an old nabble link that talks about it here. I'm not sure how I'd work around it, so I figured I'd create a pool of them. So far, I'm completely unable to find out if they are reusable or not. I know they aren't multithread safe in the sense of having 2 threads running rules at the same time, but can I reuse a session in a new thread later down the line after the last usage has called dispose()?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我最终创建了一个 KnowledgeSessionConfiguration 并在每次创建 KnowledgeSession 时重用它。无论出于何种原因(显然是一个大的类路径),创建配置对我来说非常昂贵,就像我链接的文章一样。我不确定仅创建一次 KnowledgeSessionConfiguration 并重用它会损失什么。一切似乎都在正常进行。
I ended up creating a single KnowledgeSessionConfiguration and reusing that with every creation of a KnowledgeSession. For whatever reason (apparently a large classpath), creating the configuration was extremely expensive for me, just like the article I linked. I'm not sure what I lose by creating the KnowledgeSessionConfiguration just once and reusing it. Everything seems to be behaving normally.
如果您在单独的上下文中创建知识库,那么创建 statefulKnowledgeSessions 并不昂贵。您只需避免每次需要会话时都编译规则(builder.add())。您可以为每个请求创建一个新会话并对其进行处理以避免内存泄漏,我认为您可以很好地创建会话而不是尝试重用它们。
干杯
If you create the knowledge base in a separate context, then creating a statefulKnowledgeSessions is not expensive. You only need to avoid compiling the rules every time that you need a session (builder.add()). You can create a new session per request and dispose it to avoid memory leaks, I think that you will be fine creating sessions instead of trying to reuse them.
Cheers
最近我正在使用 Drools 创建一个规则引擎应用程序。我也遇到过类似的情况。
我最终使用了基于 Apache GenericObjectPool 接口的 KieSession 池。您所需要的只是提供一种创建和销毁 KieSession 对象的方法。
使用池,您可以将借用的 KieSession 对象返回给池,或者简单地使其无效(这反过来会处置并因此释放内存)。简单地将其返回到池并不能解决问题,因为规则触发后 KieSession 工作内存是脏。另外,简单地删除事实句柄并不能解决这个问题,因为 KieSession 引用了更多对象,例如(agenda、globalResolver、kieBaseEventListeners、ruleRuntimeEventSupport、defaultEntryPoint、timerService、initialFactHandle),这些对象也是脏的。
幸运的是,StatefulKnowledgeSessionImpl提供了重置 KieSession 的功能,从而恢复所有这些对象并使其像新创建的 KieSession 一样。您需要自己比较哪一种对您来说成本更高,简单地创建一个新的或重置现有的。
另一个方面是,在使用 KieSession 作为池之后,如果池配置了最佳 minIdle 值,那么您将不需要随时创建会话,这将始终确保最小 KieSessions 对象始终在池中,因此在执行规则时不需要创建会话对象。
Recently I was creating a rule engine application using Drools. I came across similar situation.
I ended up using a KieSession pool based out of Apache GenericObjectPool interface. All you need is to give a way to create and destroy the KieSession object.
Using pool either you can return the borrowed KieSession object back to Pool or simply invalidate it (which in turn will dispose and hence release memory). Simply returning it to Pool wont solve the problem as the KieSession working memory is dirty after the rule firing. Also simply deleting fact handles wont solve it because there are lot more objects like (agenda, globalResolver, kieBaseEventListeners, ruleRuntimeEventSupport, defaultEntryPoint, timerService, initialFactHandle) are referenced by KieSession which are also dirty.
Fortunately StatefulKnowledgeSessionImpl provide a function to reset KieSession which in turn restores all these object and make it like newly created KieSession. You need to compare it yourself which one is more costly for you, simple creating a new one or reseting existing one.
Another aspect is after using KieSession as Pool you wont exactly need to create the sessions on the go if pool is configured with optimum minIdle value which will always make sure that minimum KieSessions object are always in the pool and hence there wont be any need of creating Session Objects while executing rules.