我正在使用Drools 5.6.0,並且我已準備好升級到6.0,因此此問題對於這兩個版本都是相關的。Drools singleton StatefulKnowledgeSession作爲Web服務
我已經google了很多關於在多線程環境中使用Drools,我仍然不確定如何繼續。在下面的場景中,我試圖找到一種方法來使用單身StatefulKnowledgeSession預初始化,其中有大量的靜態事實作爲Web服務的業務邏輯。
我想知道下面進一步描述的場景是否有最佳做法。
我創建了一個StatefulKnowlegdeSession單當服務器在初始化我插入超過10萬分的事實進入StatefulKnowlegdeSession開始
權。我稱這些爲「靜態事實」,因爲它們永遠不會被規則修改。靜態事實更像是一組大查找表。
現在規則引擎被放入網絡服務(Tomcat)。 Web服務接收一個將被插入到KnowledgeSession中的Request對象。 fireAllRules()之後我期望KnowledgeSession計算一個要作爲Web服務響應返回的輸出對象。
響應的計算利用了靜態事實。規則創建了很多臨時對象,這些對象使用insertLogical()插入到工作內存中。這可確保在Web服務調用結束時收回原始請求對象後,所有垃圾將從工作內存中移除。
現在的問題是我將如何使這項工作在多線程服務器?
儘可能我想,因爲靜態的事實是大隻使用一個StatefulKnowledgeSession實例(單),它可能成爲一個內存問題。
我不能使用在每個Web服務調用開始時新創建的StatelessKnowledgeSessions,因爲插入所有靜態事實將花費太長時間。我知道StatefulKnowlegdeSession不是線程安全的這個事實。此外,分區選項不再受支持。
但是,可以從不同的線程使用不同的WorkingMemoryEntryPoints/EntryPoints。我可以使用EntryPoints的池,並且每個Web服務調用都將使用池中的一個實例來插入Web服務請求。
這也意味着,我需要每使用一個特定的入口點,或者至少第一規則加倍重視自己的規則,搭配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
後續規則會在工作記憶中創建臨時對象,並且在這一點上,如果我要用幾十個併發請求轟炸引擎,我真的害怕搞亂某些東西。
- 我也可以開始「fireUntilHalt」模式KnowledgeSession但在這種情況下,我不知道我怎麼能得到規則引擎同步響應返回其作爲Web服務響應。
你不使用EntryPoints的原因是什麼?規則庫複雜度較高? KnowledgeSession中的併發問題?整體複雜性更高? – balazs
@balazs入口點就像另一個屬性一樣,但是你必須以一種不合理的方式聲明可能的值,即「from」,並且你必須重複規則,因爲你的規則不應該有所不同。在這種情況下,我會在使用EP之前調查諸如添加「源」屬性或包裝器(類Source {request request;})等選項。 – laune