我目前在drools服务器上遇到了一个问题。
我们收到相当大的请求到我们的drools服务器场,它抛出一个 OutOfMemoryError
. 那些大的请求不应该被处理(它们是bug),如果一个请求需要5秒以上的时间,它应该被取消。
我尝试用一个自定义超时drl规则来解决这个问题,这里解释了:
rule "Stop the rule engine after 5s"
timer ( int: 5s )
salience 0
when
then
System.err.println("***Stop the rule engine after 5s***");
drools.halt();
end
但这条规则从未被考虑在内。所以我尝试了另一种解决方法:把我的 ksession.fireAllRules();
在一个线程中,如果需要5秒以上的时间,用 ksession.halt();
; 这样地:
KieSessionConfiguration conf = kieServices.newKieSessionConfiguration();
final KieSession ksession = kcontainer.newKieSession(conf);
Thread droolsThread = new Thread(new Runnable() {
public void run() {
ksession.fireAllRules();
}
}, "drools");
long tStart = System.currentTimeMillis();
droolsThread.start();
/*wait until the end of the Thread or 5 seconds max*/
while (System.currentTimeMillis() - tStart < 5000 && droolsThread.isAlive())
Thread.sleep(100);
/*if alive for more than 5 seconds stop it*/
if (droolsThread.isAlive())
{
System.err.println("timeout killing drools");
ksession.halt();
ksession.dispose();
}
在第二个场景中,当用 ksession.fireAllRules();
,它开始执行请求,如果这是一个巨大的 Exception: java.lang.OutOfMemoryError
例外情况:
[apache-tomcat-9.0.39]: timeout killing drools
[apache-tomcat-9.0.39]: Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Catalina-utility-1"
java.lang.OutOfMemoryError: Java heap space
我不知道该怎么做才能阻止那些占用服务器内存的大请求。有没有可能停止一个长的请求,目前正在运行的口水?
2条答案
按热度按时间laawzig21#
您的方法是正确的,但需要使用fireuntilhalt(而不是fireallrules)启动规则执行:https://docs.drools.org/7.40.0.final/kie-api-javadoc/org/kie/api/runtime/rule/statefulrulesession.html#fireuntilhalt--
然后你就可以通过halt方法停止它。
我还建议您研究一下为什么会出现这种“吃掉所有服务器内存”的模式。也许会有机会优化你的规则。。
tzdcorbm2#
可以在statefulrulesession上使用以下api:
fireallrules(int max)在将控件返回到应用程序之前,在议程上激发匹配,直到给定的最大匹配数。
在消耗内存时,您可以分析内存使用情况(在java级别)以查看发生了什么。基于规则的应用程序通常使用从rete派生的算法进行内存处理时间权衡,从而使用大量内存