Drools 4.x升级至7.x性能大幅下降问题排查及配置优化问询
Drools 4.x 迁移至7.x性能下降原因及优化方案
可能原因
- 默认变更追踪机制的强制开销:Drools 5版本后移除了ShadowProxy配置项,默认内置了事实属性变更追踪逻辑,等价于4.x版本强制开启ShadowProxy,哪怕业务用无状态会话执行完即丢弃事实,也会产生属性快照、变更校验的额外开销,和你4.x开启ShadowProxy时性能暴跌的表现完全对应。
- 默认算法适配场景不匹配:Drools 6之后默认使用Phreak算法替代原有ReteOO算法,Phreak针对大批量事实、复杂事件处理、多规则触发场景做了优化,但是对于你这种单次仅传入2个事实、仅触发1条规则的轻量场景,Phreak的延迟求值、议程分组逻辑会产生额外开销,反而不如轻量化的老ReteOO算法性能高。
- 会话实现冗余开销:7.x的StatelessSession内部复用了StatefulSession的全生命周期管理逻辑,相比4.x极轻量化的无状态会话实现,多了上下文初始化、状态校验、资源回收的固定开销,单次执行的累计开销被放大。
- 属性访问额外开销:7.x为了支持类型安全校验、动态规则更新、新Java版本特性兼容,属性访问器的实现比4.x多了安全校验、类加载上下文切换的逻辑,你4000条规则都需要频繁读取Subscriber、Account的属性,累计的开销差距非常明显。
对应优化方案
- 切换回ReteOO算法:7.x仍保留了老ReteOO算法的实现,添加配置
conf.setOption(ReteOOOption.ENABLED);即可启用,针对轻量单次执行场景通常能带来30%以上的性能提升。 - 关闭不必要的特性开关:
- 如果你使用无状态会话、事实传入后不会修改属性,可配置
conf.setOption(PropertySpecificOption.DISABLED);关闭属性变更追踪,消除快照开销 - 不需要动态增删改规则的场景,配置
conf.setOption(RemoveRuleOption.NO);、conf.setOption(UpdateRuleOption.NO);关闭动态规则支持,减少运行时校验开销
- 如果你使用无状态会话、事实传入后不会修改属性,可配置
- 正确使用会话池:你之前遇到的AgendaFilter多次触发问题是池化会话的残留状态未清理导致的,配置
conf.setSessionPoolSize(2 * CPU核心数),每次执行完会话后调用dispose()方法主动重置状态,即可解决逻辑异常问题,同时消除每次新建会话的初始化开销。 - 规则结构优化:4000条结构完全一致的规则可以合并为单条规则加参数匹配逻辑,或者改用决策表实现,大幅提升Rete节点的共享率,减少规则匹配的遍历开销。同时可以将
activation-group替换为agenda-group手动控制焦点,减少7.x activation-group实现的锁开销。 - JVM层面优化:使用Java 11及以上版本运行,开启C2编译器激进优化:
-XX:+TieredCompilation -XX:TieredStopAtLevel=4,将Drools核心包加入JIT预编译列表,减少解释执行的开销。
内容的提问来源于stack exchange,提问作者Dimitri Gamkrelidze
相关产品推荐
相关产品推荐

