升级OptaPlanner 8后SolverFactory创建耗时剧增如何优化?
OptaPlanner 8版本SolverFactory创建耗时过高优化方案
核心原因
OptaPlanner 8.x版本中,如果你通过setScoreDrlFileList方法传入DRL评分规则文件,每次创建SolverFactory时都会触发全量的Drools规则编译流程,这部分重CPU操作就是耗时从200ms涨到4000ms以上的核心原因。你在7.x版本中直接传入预构建的KieBase,跳过了每次实例创建时的规则编译步骤,因此性能表现更好。
可落地优化方案
- 优先复用SolverFactory实例
SolverFactory本身是线程安全的,只要评分规则、求解配置没有动态变更,不需要针对每次请求新建SolverFactory。只需要在应用启动阶段初始化一次全局单例的SolverFactory,后续需要生成求解器时直接调用solverFactory.buildSolver()即可,改造成本最低,可完全消除重复创建的开销。 - 传入预编译的KieBase,对齐7.x版本的使用逻辑
不要让OptaPlanner在创建SolverFactory时临时编译DRL文件,改为在应用启动阶段提前把所有评分规则编译为KieBase实例全局缓存,创建SolverFactory时直接传入预构建好的KieBase,跳过编译步骤。参考代码如下:// 应用启动阶段执行一次,全局复用 KieServices kieServices = KieServices.Factory.get(); KieFileSystem kieFileSystem = kieServices.newKieFileSystem(); for (File drlFile : drlFileList) { kieFileSystem.write(ResourceFactory.newFileResource(drlFile)); } KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem).buildAll(); KieBase prebuiltKieBase = kieServices.newKieContainer(kieBuilder.getKieModule().getReleaseId()).getKieBase(); // 业务流程中创建SolverFactory时直接传入预编译KieBase ScoreDirectorFactoryConfig scoreDirectorConfig = new ScoreDirectorFactoryConfig(); scoreDirectorConfig.setKieBase(prebuiltKieBase); solverConfig.setScoreDirectorFactoryConfig(scoreDirectorConfig); SolverFactory<Solution_> solverFactory = SolverFactory.create(solverConfig); - 长期方案:用约束流(Constraint Streams)替换Score DRL
OptaPlanner 8.x版本开始主推Constraint Streams作为评分规则的首选实现方式,在8.22及后续版本中已经做了大量构建性能优化,规则加载速度远高于DRL,同时避免了Drools规则编译的额外开销,长期可维护性也更好。
注意:Drools规则编译属于CPU密集型的重初始化操作,本身设计为应用启动阶段执行一次的逻辑,禁止放在高频业务请求链路中动态执行,否则必然会出现严重的性能问题。
内容的提问来源于stack exchange,提问作者August Ge
相关产品推荐
相关产品推荐

