问题
I have built a Drools Rules Template using Drools 6.4.0.Final
It is pretty much identical to the example provided here.
I have wrapped it in a Spring
RestController
and deployed it as a WAR in to Tomcat
.
I notice that the first call is always very slow to get a result and gets slower as the number of rows in the xls
spreadsheet grows.
I imagine drools builds an index when the first ever KieSession
is created. And that this index is subsequently cached making further calls much faster?
I see the same behaviour when invoking directly from unit tests. First test is slow and subsequent tests are 1000 times faster.
For example, I see first call take 30secs and every subsequent call take 20ms where the spreadsheet has ~1000 rows.
Is there a way to force this "indexing" step to happen when the web application server (Tomcat
) is starting up?
回答1:
In the example you have linked, there is a line that is doing more than what it appears to be doing. The line I'm talking about is:
KieSession ksession = kc.newKieSession( "DTableWithTemplateKS" );
One of the steps inside KieContainer.newKieSession()
is to create the KieBase the specified KieSession
belongs to. A KieBase
is the binary representation of your rules. Once a KieBase
is built, it can be used to spawn multiple KieSessions
(their runtime counterpart). The creation of a KieBase
could be very time consuming. Spawning new KieSessions
from it it is not.
The KieContainer
class uses an internal Map to keep a reference to the KieBases
that were already built. The first time you ask KieContainer
for a KieSession
the KieContainer
has first to build the KieBase
. Following invocations of newKieSession()
will reuse the KieBase already built. Note that this is true as long as you always ask for the same KieSession
. Try having multiple KieBases
and ask for different KieSessions
from them and you will see that the first time you ask for a KieSession
from a new KieBase
you will experience this delay.
One thing you could do is to ask KieContainer
for your KieBase
when your app is starting. You can do this by either executing kc.newKieSession( "XXX" );
or kc.getKieBase("YYY");
Hope it helps,
来源:https://stackoverflow.com/questions/38247847/drools-rules-template-first-invocation-1000-times-slower-than-subsequence-invo