Drools规则更新:免重建会话更新规则及重索引机制咨询
Drools高频规则更新场景技术问题解答
1. 不重新创建会话的前提下能否更新已有规则
完全可以。Drools 6及以上版本原生支持规则增量热更新,不需要销毁重建KieSession,会话中已插入的Fact对象、全局变量、会话状态都能保留:
- 实现时不要把规则包打包成静态不可变的KieModule,初始化时通过
KieFileSystem托管规则源,对接数据库的规则存储即可 - 检测到数据库规则变更时,把变更的规则内容写入
KieFileSystem,调用KieBuilder.buildAll()触发增量编译,这个过程只会重新编译改动过的规则文件,不会全量编译所有存量规则 - 编译无报错后调用
KieContainer.updateToVersion()发布新版本规则,已创建的KieSession会自动同步规则变更,后续的规则匹配、fireAllRules调用都会直接走新规则逻辑 - 要注意规则依赖的业务模型类要保持兼容,不要在规则更新时随意修改类字段结构,否则会触发类加载异常,高频更新场景建议把业务模型和规则逻辑做拆分,模型类尽量稳定,只动态变更规则drl内容。
2. 规则更新操作时是否会触发类重索引处理
会触发增量范围的重索引,不会全量重建整个Rete网络和索引:
- Drools底层基于ReteOO算法实现规则匹配,规则增量更新时只会移除被删除/修改规则对应的Rete节点分支,新增规则时只会追加对应新节点,不会重建初始化会话时生成的整个类树、Rete网络结构
- 索引重建只会覆盖变更规则关联的Fact类型:比如你修改的规则只匹配
User类型的事实,那只会重新索引会话中已存在的User类型对象,其他类型Fact的索引完全不受影响 - 重索引的性能开销和变更规则的复杂度、关联类型的Fact存量正相关,高频更新场景建议控制单次提交的规则变更数量,不要单次批量提交上百条规则改动,避免短时间索引重算占用过多CPU资源。
高频更新场景调优提示:可以关闭KieSession的规则历史快照缓存,多线程规则评估开关建议保持关闭(该模式下增量更新的锁开销会高30%以上),单批次规则更新间隔建议不低于100ms,避免频繁增量编译触发JVM内存碎片问题。
内容的提问来源于stack exchange,提问作者Ankush Choubey
相关产品推荐
相关产品推荐

