在drools中处理长fireallrules

w8rqjzmb  于 2021-07-11  发布在  Java
关注(0)|答案(2)|浏览(730)

我目前在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

我不知道该怎么做才能阻止那些占用服务器内存的大请求。有没有可能停止一个长的请求,目前正在运行的口水?

laawzig2

laawzig21#

您的方法是正确的,但需要使用fireuntilhalt(而不是fireallrules)启动规则执行:https://docs.drools.org/7.40.0.final/kie-api-javadoc/org/kie/api/runtime/rule/statefulrulesession.html#fireuntilhalt--
然后你就可以通过halt方法停止它。
我还建议您研究一下为什么会出现这种“吃掉所有服务器内存”的模式。也许会有机会优化你的规则。。

tzdcorbm

tzdcorbm2#

可以在statefulrulesession上使用以下api:
fireallrules(int max)在将控件返回到应用程序之前,在议程上激发匹配,直到给定的最大匹配数。
在消耗内存时,您可以分析内存使用情况(在java级别)以查看发生了什么。基于规则的应用程序通常使用从rete派生的算法进行内存处理时间权衡,从而使用大量内存

相关问题