Drools多线程应用中JIT编译警告问题咨询
关于Drools多线程环境下MVEL约束JIT警告的分析与建议
嗨,针对你遇到的这个Drools警告问题,我来帮你梳理清楚核心要点和解决方案:
先理解警告的本质
首先你提到的这个警告:
2018-01-24 09:17:16.223 AM [drools-worker-4] WARN o.d.c.rule.constraint.MvelConstraint - Exception jitting : driveable == 'Y'
确实如你所说,它不是错误,不会影响规则的正确执行——Drools在尝试将MVEL约束表达式JIT编译为字节码以提升执行性能时失败了,会自动降级为解释模式评估约束。但这里要注意:解释模式的执行效率会比JIT编译后的模式低不少,如果这个约束是高频执行的,长期下来可能会累积性能损耗。
核心问题:是否需要调整约束评估顺序?
答案是:调整约束顺序和JIT警告本身没有直接因果关系,但合理的约束顺序可以缓解JIT失败带来的性能影响,具体分两种情况看:
1. 约束顺序不是JIT失败的原因
JIT编译失败通常和以下因素相关,和约束顺序无关:
- 表达式本身的写法:比如你用的
driveable == 'Y',MVEL的JIT编译器对字符串的==运算符处理可能存在兼容性问题(虽然Drools允许用单引号表示字符串,但MVEL底层对单引号字符串的JIT支持可能不如双引号或equals方法)。 - JVM的JIT配置:比如是否开启了JIT编译、是否有禁用特定的JIT优化选项,或者多线程环境下类加载的冲突。
- Drools版本的bug:你用的6.5.0.Final是比较老的版本,后续版本修复了不少MVEL JIT相关的问题。
2. 但合理调整约束顺序可以优化性能
如果这个JIT失败的约束无法快速修复,调整约束顺序能有效减少解释模式的执行次数:
- 把能快速过滤大量事实、且JIT编译成功的约束放在规则的最前面。比如如果你的规则里还有
status == "ACTIVE"这类简单的字段比较约束,先执行它可以排除大部分不符合条件的事实,减少后续需要评估driveable == 'Y'的次数,从而降低解释模式带来的性能开销。 - 遵循“低开销优先”原则:优先执行字段直接比较(如
age > 18),再执行方法调用(如isDriveable());优先执行能排除更多事实的约束。
具体的解决建议
步骤1:修复表达式写法,尝试解决JIT失败
把约束中的driveable == 'Y'改成更规范的写法:
- 用双引号表示字符串:
driveable == "Y"(Drools官方更推荐双引号,MVEL的JIT对双引号字符串的支持更稳定) - 或者用
equals方法:driveable.equals("Y")(更符合Java字符串比较的规范,MVEL JIT编译成功率更高)
修改后观察警告是否消失,这是最直接解决JIT警告的方法。
步骤2:优化规则的约束顺序
如果JIT警告无法消除,调整约束顺序来降低性能影响:
// 优化前 rule "Example Rule" when Vehicle(driveable == 'Y', status == "ACTIVE") then // 规则逻辑 end // 优化后:把JIT友好、快速过滤的约束放在前面 rule "Example Rule" when Vehicle(status == "ACTIVE", driveable == 'Y') then // 规则逻辑 end
步骤3:其他可选优化
- 检查JVM参数:确保没有禁用JIT编译(比如不要加
-Xint参数),可以尝试添加-XX:+PrintCompilation参数查看JIT编译的详细日志,定位具体失败原因。 - 考虑升级Drools版本:如果业务允许,升级到较新的版本(比如7.x系列),这些版本修复了不少MVEL JIT的兼容性问题,性能也有提升。
总结
这个警告不影响功能正确性,但如果性能有瓶颈,优先尝试修复表达式写法解决JIT失败;如果无法解决,通过调整约束顺序来减少解释模式的执行次数,降低性能损耗。
内容的提问来源于stack exchange,提问作者Suresh
相关产品推荐
相关产品推荐

