Drools - 与多个请求相同的KieSession

时间:2016-09-29 14:04:21

标签: drools

我在我的项目中使用了drools 6.3.0。我有大约3千条规则,有2个类别。比如说,category1有1500条规则,category2有1500条规则。 有不同数据的20k订单。每个订单都有一组不同的属性。现在,为每个请求创建kiesession需要时间,而且速度非常慢。因此,计划使用相同的kiesession执行所有订单和订单将使用多线程进行处理。

以下是我目前的做法。

 KieBase kieBase = null;
 KieServices kieServices = KieServices.Factory.get();
 KieRepository kieRepository = kieServices.getRepository();
        kieRepository.addKieModule(new KieModule() {
            @Override
            public ReleaseId getReleaseId() {
                return kieRepository.getDefaultReleaseId();
            }
        });

 KieFileSystem kfs = kieServices.newKieFileSystem();

 kfs.write(******);  // Load 3k rules in a for loop
 KieBuilder kb = kieServices.newKieBuilder(kfs);
            kb.buildAll();
 KieContainer kContainer = kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
 kieBase = kContainer.getKieBase();

 kContainer = kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
            kieBase = kContainer.getKieBase();
 KieSession kieSession = kieBase.newKieSession();

这就是我创建kiesession的方式,并希望将此kiesession用于所有订单执行。

我想使用线程池并行执行订单。

这就是

//这里的条目基于类别和一些id。 每条规则都有id和category。对于每个id和cateogory,都会有一组应该被评估的规则。

流程就像,

1)从DB获取20k订单 2)对于每个订单,获取要执行的ID 3)对于每个id,格式入口点如entry = id+_category

4)插入订单属性数据和fireRules。

final EntryPoint entryPoint = ksession.getEntryPoint(entry);
        if (entryPoint != null) {
            entryPoint.insert(data);
            ksession.fireAllRules();
        } else {
            log.warn("No rules to be executed");
        }

现在,因为我必须并行执行订单,

每个订单都会在parallal中调用以下代码,

entryPoint.insert(data);
ksession.fireAllRules();

因为,每个订单都有不同的属性并将不同的数据插入入口点,这会导致问题并且无法获得预期的结果。

无论如何要实现这个目标吗?

由于

2 个答案:

答案 0 :(得分:0)

不是超级专家,但我正在寻找类似的东西,我认为答案是将这些调用变为同步块...这根本不是并行执行或者是使用改为CloseableIterator<StreamResult<T>>,它将使用自己的工作内存为执行调用创建一个常规StatelessKieSession本地,因此它只会传入您传入KieSession的数据对象。

令人惊讶的是,与重复使用单个常规会话并在触发规则之间清除其中的对象相比,使用无状态会话似乎并不显着更耗时。

答案 1 :(得分:0)

也许您应该使用原型会话。在kmodule.xml文件中添加:

<ksession name="YourSessionName" type="stateful" default="false" clockType="realtime" scope="prototype"/>