亲身经历, 在Windows 10 21H2这个系统版本里, 对Drools 7.73.0进行实测, 遭遇了分层规则完全无法生效的严重状况, 就像掉进大坑一样, 而新手只要按照步骤一步步去操作, 便……
亲身经历, 在Windows 10 21H2这个系统版本里, 对Drools 7.73.0进行实测, 遭遇了分层规则完全无法生效的严重状况, 就像掉进大坑一样, 而新手只要按照步骤一步步去操作, 便能够轻易地躲开这类常见的问题。
第一步 创建基础决策表并绑定实体
开启IDE, 于src/main/resources之下全新创建文件夹rules, 接着通过右键方式去创建DecisionTable.xls。运用Excel将其打开, 于第一行书写RuleSet, 在第二行填入com.example.rules, 在第三行把Import填写为com.example.model.Order。第四行予以留空情况, 在第五行写下以OrderLevel_作为前缀的RuleTable。
新手要避开这样的坑 , 好多人竟直接就按普通表格那样来写Excel , 却忘掉了第一行得称作RuleSet才行 , 不然DRL文件生成就会失败。报错呈现为null pointer , 是在编译阶段出现的。解决之道是 , 去检查Excel第一列第一行的字母有没有拼错 , 并且不能有多余的空格。
表格的列头写上CONDITION, 以及ACTION, 在条件那一列下方填写orderAmount > 100这句话, 而在动作那一列那里填入order.setLevel(“VIP”)这个内容。在进行保存操作的时候, 文件编码要选择UTF-8, 而不要去使用默认的ANSI。
第二步 在规则文件中引入分层配置
新建一个名为src/main/resources/application.properties的文件, 在该文件里面写入drools.rulebase.group=default这样的内容。
有人将kmodule.xml放到了错误的目录, 在启动的时候日志显示No knowledge base found, 核心的原因是, 对于Maven项目而言, 应该放置在src/main/resources/META-INF这个位置, 而并非resources根目录。要是出现了ClassNotFoundException, 那就去查看pom.xml文件当中是否存在着drools-compiler依赖, 而且该版本一定要与Drools版本相互匹配才行。
关键之处在于分层配置耶, 在第一层的规则文件当中写入salience 10, 于第二层写入salience 5, 如此这般能让优先级比较高的先去施行。在实际的项目里面, 我在第一层处理黑名单过滤的事宜, 在第二层处理正常积分计算的事儿。
第三步 加载规则并触发分层校验
写Java代码加载KieSession:
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("orderKSession");
然后插入事实对象并执行:
Order order = new Order(150.0);
kSession.insert(order);
kSession.fireAllRules();
kSession.dispose();
有新手需要避开的坑, 在运行完成 fireAllRules 之后, 发现 order.getLevel() 返回的是 null , 存在常见的报错情况, 先是 Rule execution error , 之后再跟着 Failed to compile。有种情况是这样的: 在 Excel 里, CONDITION 列使用了中文括号或者逗号作为符号, 结果就这样了, Drools 解析的时候出问题崩塌了。应对的解决举措是: 将所有符号都切换成英文半角状态。接着还有另一个缘由: 实体类名为 Order 的, 没有编写 getter/setter 方法, 这导致 Drools 通过反射进行调用的时候失败了怎么办呢。增添 Lombok 注解或者手动书写就能够解决这个问题了。
将关键参数的推荐值设定为: salience处我采用5, 原因在于, 层次数量增多时易于产生混乱状况, 5与10足以对两层实施区分, 若再于向上的方向添加为20、30, 反而会致使维护难度加大, 出现故障时排查成本会变高。
进行两种方案的对比, 方案A是将所有规则写于一个Excel里, 仅作sheet划分, 方案B是每层都单独有一个Excel文件, 放置于不同的包路径。方案A适用于规则总数少于50条的小项目, 修改一个文件便可完成。方案B适用于有上百条规则的分层场景, 像是电商促销与风控分开维护, 在团队协作时彼此互不干扰。倘若要选取方案B, 那就务必要留意了, 于kmodule.xml之中, packages那里所写的乃是多个包, 这些包以逗号来进行分隔。
高频报错的解决办法是, 在运行的时候出现了 Unable to create kie session 的情况, 并且还附加了 java.lang.RuntimeException: Unknown KieSession name。解决流程是, 在第一步的时候, 要去检查, kmodule.xml 当中的 ksession name, 以及代码里 newKieSession 的字符串, 二者是否达成一致, 还要留意大小写情况。第二步, 要去确认, kbase 的 packages 属性所填的那个包名, 跟 Excel RuleSet 行所填的包名是一样的。第三步, 需清掉 target 目录, 之后重新进行编译, 这是因为, Drools 缓存了旧的 kmodel 文件, 要是不清理的话, 就会一直读取老配置。
有一种方法, 它仅仅适用于那种规则数量处于200条以内的中小型项目, 一旦超过了这个规模, 就建议拿去Drools Workbench那儿做可视化的分层。还有一种替代的方案, 就是在使用Spring Boot去集成Drools的时候, 要把每一层的规则放置在不同的被@Bean修饰的KieContainer里面, 并且要手动地去控制调用的顺序。
微信扫一扫
还没有评论呢,快来抢沙发~