ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

JRules规则项目新建全流程:从XOM/BOM到RuleSet部署

JRules规则项目新建全流程:从XOM/BOM到RuleSet部署 上周在技术群里又有人抛老问题Java 规则引擎哪个好下面清一色在聊 Drools、Easy Rules、RuleBook。我看了半天回了一句如果你们公司还跑着 WebSphere ILOG JRules 的老系统这个问题就得换个问法——怎么把这套老牌规则引擎里的规则项目重新跑起来。从 JRules 7.1 一路用到 8.x再到看它改名叫 IBM ODM我这些年接手、重构过不少规则项目深深觉得这类存量系统的难点从来不是规则写不出来而是第一步就卡住很多人连“新建一个规则项目”都建不对。这篇是规则引擎连载的第三篇前两篇聊了规则引擎能解决什么问题、整体架构大概长什么样这篇就直接落到实操讲清楚在 JRules 里新建一个规则项目的完整链路项目结构、创建步骤、BOM/XOM 这些绕不开的概念、以及第一次跑通规则时最容易踩的坑。适合两类人看一类是刚拿到老项目、必须在 Rule Studio 里改规则的开发者另一类是还在评估要不要选 JRules 这类重型规则引擎框架、想先看看它开发手感的人。1. 先搞清楚JRules 的“规则项目”和普通 Java 项目差在哪1.1 规则项目的资产结构XOM、BOM、词汇表、规则集很多第一次接触 JRules 的人最大的误解是以为规则项目就是个 Java 项目无非多几个规则文件。实际上JRules 的 Rule Project 从设计上就不是为了让你写 Java 代码而是为了管理“规则资产”而存在的。普通 Java 项目里代码是唯一的主角src/main/java下面全是类和接口。但在 JRules 里核心资产至少分成四层资产层作用谁主要维护XOM规则真正要调用的 Java 对象模型可以是普通 POJO也可以是从业务系统暴露出来的方法开发人员BOM业务对象模型把 XOM 里的类名、方法名、属性名包装成业务人员能看懂的概念开发人员/规则架构师Vocabulary词汇表把 BOM 里的概念继续加工成“至少”“不得”“享受折扣”这类业务短语规则架构师/业务分析人员RuleSet规则集存放具体规则用接近自然语言的方式描述业务逻辑规则开发者/业务人员这句话得多说两遍XOM 是给“机器执行”看的BOM/Vocabulary 是给“业务理解”看的RuleSet 才是业务逻辑真正待的地方。新建规则项目本质上是把这四层资产的仓库先建起来而不是简简单单建一个空目录。1.2 用电商会员折扣举个例子假设现在要做一条逻辑黄金会员在下单时享受 8 折。传统 Java 实现是在订单服务里写if (GOLD.equals(customer.getGrade())) { order.setDiscount(new BigDecimal(0.8)); }业务要改成“黄金会员 75 折、白银会员 95 折”你就得改代码、走发布流程。JRules 的思路是把这种条件判断从代码里拿出来放到规则项目里变成类似if the grade of the customer is GOLD then set the discount of the order to 0.8;要让这行规则能跑通底层 XOM 里必须有Customer.getGrade()和Order.setDiscount()BOM 里必须把Customer说成“客户”、grade说成“会员等级”Vocabulary 里还要把is对应到equals。这四个环节少了哪一个规则要么编译不过要么在规则编辑器里根本打不出来业务人员看着就是一团乱码。所以新建规则项目这件事重点不是“点几个下一步”而是把你接下来的资产怎么组织、怎么命名、怎么映射提前想明白。2. 在 Rule Studio 里新建一个 Rule Project 的完整流程2.1 环境准备JRules 各版本的开发工具叫法不太一样老版本通常叫 Rule Studio后来的 IBM ODM 版本里叫 Rule Designer下面统一叫它 Rule Studio。不管叫法怎么变它本质上是 Eclipse 插件集所以你第一步要装对环境。我建议你开工前先确认四件事Rule Studio 版本和你要连的 Rule Execution ServerRES版本一致至少大版本不能差太远。比如 8.x 的规则项目导出到 7.1 的 RES 就很容易失败。JDK 版本和 Rule Studio 要求的匹配。JRules 7.x 时代很多环境还是 JDK 1.5/1.6后来 8.x 才逐步支持更高版本你用高版本 JDK 打开老工作区大概率会报UnsupportedClassVersionError。工作区编码统一。这一步最容易忽略后面中文注释和规则文本全乱码就是在这里埋下的雷。确认你是用“Rule Studio 的工作区”打开项目而不是用普通 Eclipse 直接双击.project文件。规则项目带专门的 Project Nature普通 Eclipse 没有对应插件时会把它当成未知工程。这些听起来都是小事但我真见过有人在这上面耗掉一整天。老工具不像现代 IDE 装完就能自动识别环境不匹配时错误信息往往还很暧昧。2.2 新建 Rule Project 的向导步骤下面以我比较常用的 JRules 7.1/8.x 界面为例不同版本按钮位置会有一点偏移但流程是通用的。打开 Rule Studio选择File - New - Other在向导里搜索“Rule Project”。如果这个入口没有确认你已经切到 Rule Studio 相关的 Perspective通常是Window - Perspective - Open Perspective - Other里选规则开发透视图。输入项目名称。我习惯用Rule_OrderDiscount这种命名规则项目名称一般不带版本号版本号放在 RuleApp 层管理。如果公司有固定的工作区规范设置项目存放路径没有特殊要求就保持默认。向导后面会问要不要把项目同时创建成“Java 项目”在多数版本里规则项目本身就带 Java 能力建议保留因为 XOM 的 Java 类往往就放在这个项目里。根据版本不同可能还有一步是让你选目标 RuleApp 或者 Execution Server 类型。这一项不选也可以后面再配但如果你明确知道要部署到哪套环境最好在这里就选好后续导出 RuleApp 时能少折腾。点Finish。到这里项目已经在资源管理器里出现了。注意你建的如果是普通 Java Project那这一步开始就错了后面在规则编辑器里怎么看怎么别扭。新建规则项目最怕的就是“用 Java 工程的思维硬套”所以向导里只要看到 Rule Project 相关选项优先选它。2.3 建完后的默认结构和 Rule Explorer新建完成之后你不会像 Maven 项目那样看到一个标准的src/main/java。不同版本生成的目录结构会有差异但通常会包含类似下面这些内容MyRuleProject ├── .project ├── .classpath ├── configuration ├── rules │ └── ... ├── src │ └── ... └── .settings千万不要急着往里堆.java文件。你先打开 Rule Studio 里的规则透视图注意它和 Eclipse 的Package Explorer不一样它会有一个专门的规则资源视图一般叫Rule Explorer或Rules Explorer里面不是按包名一层层展开而是按Rule ProjectBOMVocabularyRuleSetXOM这样的资产维度展示。初次看到这个视图的人容易慌因为找不到自己熟悉的 Java 包结构。我的建议是你必须适应它因为后面所有新建 BOM、词汇表、规则集的操作入口都在这里这才是 JRules 项目真正的“主目录”。3. 项目建完先别急着写规则把 XOM/BOM/Vocabulary 这一串关系搭好3.1 先搭 XOM规则引擎真正执行的那些类XOM 是规则引擎的“执行底座”。JRules 本身不替你写业务对象的 getter/setter它只知道调用 Java 方法。你先得把规则要操作的类准备好。创建 XOM 有两种常见做法直接在规则项目里新建一个 Java 类作为 XOM。在另一个普通 Java 项目里维护业务模型然后在规则项目里添加项目依赖。我更推荐第二种因为业务模型往往不只在规则项目里被使用。如果业务系统已经有一个customer-service项目里面的Customer对象已经存在你没必要在规则项目里复制一份。直接在项目属性 - Java Build Path - Projects里把那个 Java 项目加进来即可。一个最简的 XOM 类大概长这样package com.example.order.model; import java.math.BigDecimal; public class Customer { private String grade; private BigDecimal discount; public String getGrade() { return grade; } public void setGrade(String grade) { this.grade grade; } public BigDecimal getDiscount() { return discount; } public void setDiscount(BigDecimal discount) { this.discount discount; } }注意一点规则引擎最终是通过反射或直接字节码调用来访问这些类的方法名、属性名都会被 BOM/Vocabulary 引用。一旦发布到 RES 之后再改方法名规则项目里凡是引用了旧名字的地方全部要跟着改。所以 XOM 的命名要像定协议一样谨慎。3.2 从 XOM 到 BOM让规则说人话XOM 里是一个叫Customer.getGrade()的方法业务不会这么说话。BOM 干的事就是把Customer.grade包装成业务概念“客户等级”。在 Rule Explorer 里选中你的 Rule Project右键新建一个 BOM。BOM 创建后你需要把 XOM 里的类映射过来。大多数版本的编辑器里有一个“添加映射”之类的入口选择包、类然后逐个映射属性和方法。比较常见的操作是把Customer映射为“客户”。把grade映射为“客户等级”。把discount映射为“折扣”。把getGrade()映射为“客户等级值”。这一步做完你在规则编辑器里输入“客户”IDE 才能联想出相关属性和方法。如果发现规则里输入什么联想都没有别急着怀疑语法先回 BOM 里检查映射有没有生效。3.3 设置 Vocabulary搞定“至少”“折扣为”这种业务词汇BOM 解决了“对象叫什么”Vocabulary 解决“运算关系怎么说”。同一个在规则里可能被业务人员说成“至少”“不低于”“超过或等于”等等。JRules 的 Vocabulary 就是把这些运算符、动词、介词绑定到具体的 Java 操作上。在电商场景里你可以建一组词汇业务说法底层操作至少不超过是equals设置为setter 方法享受某个方法返回true这一步对于项目能否交给业务人员维护非常关键。很多团队把前后端开发做得很好却在 Vocabulary 上偷懒结果规则写出来仍然满屏英文方法名业务人员看都看不懂规则引擎的“业务价值”就打了对折。3.4 RuleApp 与规则集的部署路径设计项目结构建好了很多人就开始写规则完全忘了还要考虑部署单元。JRules 的部署单位叫 RuleApp一个 RuleApp 里可以包含一个或多个 RuleSet。新建项目阶段你至少要先把命名规划定下来。我的习惯是Rule Project 对应一个业务域比如“订单中心”。RuleSet 对应一个决策点比如“订单折扣计算”。RuleApp 对应一个可发布的组件比如OrderDiscountRuleApp版本号用1.0起步。为什么要在新建阶段考虑这个因为 RuleApp 一旦发布到 RES后续更新规则是整体替换还是热更新很多都取决于你的 RuleSet 拆分粒度。规则全堆在一个 RuleSet 里发布起来是大炸弹改一条会员规则可能要把整批折扣规则一起重新发布拆得太碎又会有一堆小 RuleApp 要管理。我的建议是先按决策点拆一个决策点一个 RuleSet后续发现性能问题再做合并。3.5 文件编码与 JDK 级别不然后面全是乱码和版本报错这是新建项目阶段最不起眼但最要命的一项。老牌 Java 规则引擎的项目里很多配置文件、规则文件都带编码信息。如果你在 Windows 上用默认 GBK 创建了规则项目后来团队其他人用 UTF-8 打开中文注释和规则字符串全会变成乱码。我建议在新建完项目后立刻去项目属性 - Resource - Text file encoding里显式设置成 UTF-8如果公司有统一编码规范用规范里的值。同时把.settings目录下的配置文件提交到版本控制这样别人检出后不会因为本地环境差异又变回乱码。JDK 级别也在这里一起检查。Rule Studio 项目属性里会有 Java 编译器级别选项尽量和 RES 运行环境的 JDK 保持一致。项目文件里存的是.class文件版本号规则引擎在服务器上加载这些类时如果版本不匹配报的错基本都是UnsupportedClassVersionError排查起来浪费生命。4. 用一条最简单的规则把“新建项目”这件事验证闭环4.1 新建 RuleSet 并写一条规则配置都做完以后别急着写复杂业务先用一条最简单的规则把链路跑通。新建项目这个动作本身没有验证标准真正验证标准是你的规则项目能编译、规则能执行、结果可预期。在 Rule Explorer 里右键 Rule Project新建一个 RuleSet名字就叫OrderDiscountRuleSet。有些版本里也叫 Rule Package本质一样就是一个放规则的容器。然后在 RuleSet 里新建一条规则我这里用接近 BAL商务动作语言的写法示意具体语法以你安装版本生成的模板为准rule GoldCustomerDiscount when { Customer( grade GOLD ); } then { Customer.setDiscount( new BigDecimal(0.8) ); }如果你用了 BOM/Vocabulary编辑器里也可以切到业务语言视图看到的效果更像if the grade of the customer is GOLD then set the discount of the customer to 0.8;第一次写规则不要追求复杂关键是确认这条规则能被规则编译器解析、BOM 映射正确、字段名称没打错。如果这一步 IDE 有红叉优先双击看错误定位大部分都是“找不到属性”“方法签名不匹配”回去检查 BOM/XOM 映射即可。4.2 本地跑一次规则测试写完之后Rule Studio 一般支持直接在编辑器里运行规则做本地测试。你不需要先起一套 RES在开发环境里有一个轻量的规则会话容器可以用来做单测。我常用的验证方式是这样的先准备一组测试输入比如一个grade GOLD的客户对象。执行规则集让它返回或修改客户对象。检查输出结果比如discount是否变成0.8。一个最简单的验证表格大概是场景输入客户等级预期折扣结果黄金会员GOLD0.8非黄金会员NORMAL不修改实际跑的时候你会发现新手最容易在“预期结果”上翻车不是规则写错而是对象状态本身没准备好。比如Customer的discount初始值如果是null规则集不满足条件时不会覆盖它结果读到null也是对的。所以本地测试时要把初始状态定义清楚否则会误判规则执行异常。4.3 导出 RuleApp 并部署到 Rule Execution Server本地测试通过后再走一次部署验证这个新项目才算真正“活”了。在 Rule Studio 里右键规则项目选择导出相关菜单生成 RuleApp 归档文件。导出时通常会让你确认RuleApp 名称和版本。要包含哪些 RuleSet。是否要把 XOM 的依赖一起打包。我建议把 XOM 一起打包除非你的 RES 服务器上已经通过共享库的方式提前放好了模型类。第一次做项目时打包缺失是部署失败最常见的原因。服务端报ClassNotFoundException十有八九不是网络问题而是 XOM 没进 RuleApp。然后在 Rule Execution Server 的管理控制台里上传这个归档激活后通过一个测试接口调用规则集传入同样的测试数据看返回是否和本地一致。到这一步从“新建项目”到“能跑规则”的最小闭环就完成了。5. 我这些年在新项目阶段踩过的四个坑5.1 建了普通 Java Project 而不是 Rule Project这个错我见过太多次。现象是项目里能看到 Java 类但无法新建 BOM、Vocabulary、RuleSet菜单里压根没有对应入口。根因就是创建工程时选成了普通 Java Project规则项目的 Project Nature 没挂上。解决方式不是硬着头皮把规则文件手工拖进去应该在项目属性或者右键菜单里找“添加规则项目特性”之类的操作。不同版本叫法不同但思路都是给已有项目追加 JRules 的 Nature。如果找不到宁可重新建一个 Rule Project也别在错误的项目类型里硬撑。5.2 属性在 BOM 里不可见规则编辑器里输入客户对象后联想列表为空是最让人恼火的情况。这通常不是规则项目坏了而是 BOM 映射没到位。排查顺序是先看 XOM 类里是不是没有 getter/setter再看 BOM 里有没有把需要用的属性加进去最后看 Vocabulary 里是否绑定了对应词语。我当时排查过一个离谱问题Java 类里字段叫discountRategetter 写成了getDiscount()BOM 里映射时按方法名自动找结果怎么都找不到最后是肉眼看到 getter 和字段命名不一致才解决的。这种问题 IDE 不会报错只能靠耐心。5.3 中文乱码规则项目里的中文乱码经常不是规则文件本身的问题而是整个工作区默认编码不对。你在 A 电脑用 UTF-8 创建在 B 电脑用 GBK 打开目之所及全是方块。我的经验是两件事必须同时做一是项目级编码显式设成 UTF-8二是在团队里约定.settings相关文件必须提交。只改第一项同事检出后仍是各自本机默认编码只做第二项新项目第一次创建时还是会错。5.4 团队协作时 RuleApp 导出不一致同一个规则项目两个人分别导出 RuleApp如果版本控制只正常提交了rules目录没有提交完整的项目配置文件导出的归档内容就可能不一样。最典型的情况是A 在本地规则项目里加了 XOM 项目依赖B 检出后没有那个依赖导出时 Class 没被打进去部署后运行期才炸。处理办法是规则项目里跟构建路径相关的配置文件一律纳入版本控制新成员加入时用 SCM 里固定的项目集合拉代码不要自己在本机“补”依赖。我这些年做老规则项目改造最深的一点体会是JRules 这种重型规则引擎框架真正的复杂度不在规则语言本身而在项目资产的“组织方式”上。XOM、BOM、Vocabulary、RuleSet 之间的关系一旦理顺后面写规则就是水到渠成的事。反过来关系没理顺哪怕规则语法背得再熟项目也走不远。这篇把新建规则项目讲透了下一篇可以接着聊怎么把一套 RuleSet 设计成能支撑长期变化的决策服务。
返回列表