ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Drools 7.48.0.Final规则引擎实战:发行包解析与工程搭建

Drools 7.48.0.Final规则引擎实战:发行包解析与工程搭建 简介面向 Drools 7 规则引擎开发与运维人员这份打包内容对应 7.48.0.Final 官方发行版。Drools 在这一阶段已广泛用于业务规则管理、决策表、规则流与复杂事件处理等场景适合在本地快速搭建规则引擎开发环境或在生产内网中离线部署对于需要脱离公网、以固定版本交付的项目团队尤其适用。压缩包整体约 64.01MB以官方发行版形式打包可在内网环境解压后作为依赖归档便于快速获取 Drools 7.48.0 的完整运行环境也可用于对比不同版本间的 API 与配置差异减少升级迁移时遇到的类冲突和规则兼容问题。已有306人学习/下载特别适合正在将 Drools 集成到 Spring Boot、微服务架构中的 Java 后端工程师也适合准备在项目中引入规则引擎、但需要先进行版本验证和功能评估的团队参考使用。 当你在官网下载页面点下那个drools-distribution-7.48.0.Final.zip链接或者从项目公共仓库里把它拷到本地时大概率你是想跑一个规则引擎而不是真的在乎这个压缩包里装了什么。我也是这么过来的第一次拿到这个包时解压完一片茫然——里面有bin、有examples、有docs还有一大堆jar怎么看都跟网上教程里那几行Maven依赖对不上。这篇文章我就按自己的实际经验把这个包、这个版本号、以及用它搭规则引擎的完整流程给你讲透。Drools是一个基于Java的开源业务规则管理系统BRMS核心作用是把业务规则从业务代码里抽出来以规则文件.drl的形式独立维护运行期动态加载、动态执行。7.48.0.Final是Drools 7.x系列的最后一个正式版之后官方主版本转向8.x所以这个版本既保留了7.x的成熟稳定又算是整个7时代的毕业版。这篇内容适合三类人第一次接触规则引擎的Java后端、想把业务条件判断改造成规则系统的架构师、以及项目里已经在用Drools但遇到环境或运行问题的朋友。我会从包结构开始讲再落到可复现的工程代码最后把踩过的坑都摊出来。1. 拿到压缩包之后先搞明白它是什么1.1 压缩包的目录结构到底有什么解压drools-distribution-7.48.0.Final.zip之后你会看到这样几个核心目录和文件bin/存放一些可执行脚本比如启动KIE Server、Workbench用的启动脚本还有Windows下的bat和Linux下的sh。examples/官方自带的一组示例工程包含若干.drl规则文件和对应的Java调用代码适合入门翻阅。docs/离线版的Drools文档包含用户指南、规则语言参考、API文档。licenses/开源协议文本主要是Apache 2.0。upgrade/从旧版本迁移到当前版本的说明文档。README.txt包的说明和后续链接。根目录下还有kie-server和business-central两个war包或目录这取决于你下载的是精简版还是完整发行包。很多人会问我引入Maven依赖不就行了吗为什么还要下载这个distribution包答案是distribution包是给部署型使用者准备的——你想跑一个独立的KIE Server服务或者想本地起一个Workbench做规则在线管理就离不开它。如果你只是在自己的Web项目里用规则引擎Maven依赖就够了这个包主要是给你做本地调试和服务端部署用的。1.2 为什么推荐关注7.48.0.Final这个版本节点Drools的版本号规则里7.48.0是主版本和迭代号Final表示这是一个正式发布版本不是快照SNAPSHOT也不是测试版。7.48.0.Final是7.x分支的收尾版本所有特性的演进在这个版本冻结后面7.x只出安全补丁。选择这个版本有几个实际考量兼容性好JDK 8是它的主场大多数存量Java项目都用JDK 8无需为了规则引擎升级运行时。生态成熟Spring Boot、Spring Cloud的集成方案在7.x时代已经非常完善网上资料和踩坑记录都很多。行为稳定相比8.x的功能调整、模块拆分7.x的API和规则行为没有大改团队上手成本低。我见过不少团队因为追求新版本而升级到8.x或9.x现在叫KIE结果项目里自定义的Dialect、老的API过期问题一大堆。业务系统优先求稳7.48.0.Final这个节点对老工程足够友好。2. 规则引擎的核心概念十分钟过一遍2.1 规则、事实、工作内存的关系要上手Drools必须先建立三个核心概念。规则Rule用.drl文件描述的一段条件-动作逻辑格式是when部分写条件then部分写动作。事实Fact被插入规则引擎的普通Java对象规则通过匹配事实的属性来判断是否触发。工作内存Working Memory规则引擎内部的存储区域所有插入的事实都放在这里参与规则匹配。我用一句生活化的话帮你理解工作内存像一张桌子规则是贴在墙上的检查单你不断往桌上放东西事实每次放进去一个新东西Drools都会把所有检查单重新过一遍看哪些规则的条件被满足了满足的就执行动作。这里有个关键点需要特别记牢规则匹配是穷举式的不是你写了if-else的顺序执行。Drools使用Rete算法对规则条件做模式匹配同一时刻可能有多个规则同时满足条件具体执行顺序由规则的优先级salience和议程Agenda机制决定。这个特性既是Drools灵活性的来源也是新手最容易踩坑的地方——你会发现规则的执行顺序跟文件里的书写顺序并不一致。2.2 KIE平台是Drools的完整形态Drools 7时代官方把整个产品线统称为KIEKnowledge Is Everything平台包含几个核心组件Drools规则引擎本体。jBPM业务流程管理处理跨系统的流程编排。KIE Server独立部署的规则执行服务对外提供REST API。Business Central可视化的工作台用来在线管理规则、流程和部署。KIE API统一的客户端编程接口负责创建容器、加载规则、触发执行。在实际项目中最常见的组合是Maven工程引入kie-api和drools-core把.drl规则文件放在src/main/resources下代码里通过KieServices创建KieContainer和KieSession然后向KieSession插入事实并触发规则。KIE Server通常用于需要独立部署、多人协作维护规则的场景如果规则就写在应用里直接内嵌引擎更轻量。2.3 什么时候该用规则引擎什么时候不该用这东西不是万金油我说点实在的。如果你的业务规则就十几条、半年才改一次、参与判断的字段固定那用if-else完全没问题上规则引擎反而增加维护成本。但如果你遇到下面几种情况Drools就值得考虑了规则数量超过几十条且规则之间存在复杂的优先级、互斥、组合关系。规则变化频繁希望业务人员或运营人员在线调整而不频繁发版上线。同一套规则需要复用多个系统比如风控策略既要服务订单系统也要服务售后系统。规则的执行需要支持动态加载、热更新不能每次改一条规则就重启应用。我参与的一个风控项目中规则从最初的200条膨胀到2000多条用if-else根本没法维护。迁移到Drools之后规则全部抽成.drl文件每次修改只更新对应的规则包风险策略的调整周期从一周缩短到几个小时这才是规则引擎真正的价值。3. 从零搭建第一个Drools工程附完整代码3.1 环境准备JDK版本和构建工具先确认基础环境。7.48.0.Final推荐使用JDK 8JDK 11也能跑通但部分场景下因为模块化限制需要额外配置。构建工具我建议用Maven 3.6以上版本Gradle也能用但Drools官方文档主要针对Maven遇到问题查资料时Maven方案更顺。检查环境命令如下java -version # 期望输出包含 1.8.x 或 openjdk version 1.8.0_xxx mvn -version # 期望输出 Maven 3.6.3 或以上如果本地还没装Maven去官网下载二进制包解压后配置M2_HOME环境变量即可。这一步没什么难度但版本别太老Maven 3.2以前的版本拉取依赖时可能遇到TLS问题。3.2 创建工程并配置依赖我用一个最精简的Maven工程来演示。新建普通Java工程pom.xml里最少需要下面这些依赖properties drools.version7.48.0.Final/drools.version /properties dependencies dependency groupIdorg.kie/groupId artifactIdkie-api/artifactId version${drools.version}/version /dependency dependency groupIdorg.drools/groupId artifactIddrools-core/artifactId version${drools.version}/version /dependency dependency groupIdorg.drools/groupId artifactIddrools-compiler/artifactId version${drools.version}/version /dependency dependency groupIdorg.drools/groupId artifactIddrools-mvel/artifactId version${drools.version}/version /dependency dependency groupIdch.qos.logback/groupId artifactIdlogback-classic/artifactId version1.2.11/version /dependency /dependencies注意drools-mvel这个依赖。从7.x中期版本开始Drools把MVEL表达式解析器独立成模块如果不引入它编译.drl时会报找不到MVEL相关类。这个坑在官方文档里不容易注意到我一开始也被卡了半个小时。3.3 编写第一条规则和对应的事实类先定义一个简单的事实类模拟电商订单的折扣计算package com.example.rules; public class Order { private double amount; private double discount; public Order(double amount) { this.amount amount; } public double getAmount() { return amount; } public void setAmount(double amount) { this.amount amount; } public double getDiscount() { return discount; } public void setDiscount(double discount) { this.discount discount; } }然后在src/main/resources/rules/order-rules.drl里写规则package com.example.rules import com.example.rules.Order rule 满1000减100 when $order: Order(amount 1000) then $order.setDiscount(100); System.out.println(触发规则满1000减100); end rule 满500减30 when $order: Order(amount 500 amount 1000) then $order.setDiscount(30); System.out.println(触发规则满500减30); end这里有个细节规则文件第一行的package是规则逻辑包名不需要和Java包名一致它只用于归类规则但用统一的包名更便于管理。每个规则由rule关键字开始salience可以定义优先级数字越大越先执行默认值为0。3.4 用KIE API加载规则并执行写一个主类来加载规则、插入事实、触发所有规则package com.example.rules; import org.kie.api.KieServices; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; public class RuleRunner { public static void main(String[] args) { KieServices kieServices KieServices.Factory.get(); KieContainer kieContainer kieServices.getKieClasspathContainer(); KieSession kieSession kieContainer.newKieSession(); Order order new Order(1200); kieSession.insert(order); kieSession.fireAllRules(); System.out.println(最终折扣 order.getDiscount()); kieSession.dispose(); } }执行后输出如下触发规则满1000减100 最终折扣100.0这里解释一下关键API的作用getKieClasspathContainer()会扫描classpath下的META-INF/kmodule.xml和所有.drl文件构建知识库。注意Drools默认要求classpath下至少存在一个kmodule.xml文件来定义KieBase如果你不写这个文件默认也会使用一个隐式的KieBase但建议显式创建。在src/main/resources/META-INF/kmodule.xml中写入?xml version1.0 encodingUTF-8? kmodule xmlnshttp://www.drools.org/xsd/kmodule kbase nameorderKbase packagesrules ksession nameorderKsession/ /kbase /kmodule这样配置的好处是很明确的packagesrules指定只加载该包下的规则如果你想用不同的规则集服务不同业务模块就定义多个kbase。4. 实操中的常见问题和排查思路4.1 规则没有触发最常见的原因新手上路遇到最多的问题就是插入了事实fireAllRules()也调了但规则就是不触发。我列一个排查清单按顺序检查检查.drl文件是否被正确加载在启动时加-Ddrools.dump.dir/tmp/drools参数Drools会把编译后的规则输出到该目录能看到文件说明加载成功。检查事实对象的字段访问Drools里的属性引用是通过getter方法反射获取的如果字段是私有的但没有对应getter规则里写amount 1000是匹配不到的。检查规则包名和kmodule.xml中配置的packages是否一致。很多人规则文件的package写的是com.examplekmodule里却写packagesrules等于整个KieBase是空的。检查fireAllRules()是否覆盖了全部规则。默认情况下会触发所有激活的规则但如果你用了fireAllRules(int max)限定了数量后面的规则就不执行了。4.2 类冲突和依赖版本冲突Drools的依赖树比较复杂最容易出问题的就是drools-core和drools-compiler版本不一致。比如你的传递依赖里某个第三方模块引入了旧版Drools就可能导致运行时报NoSuchMethodError或ClassNotFoundException。解决方案是强制锁定版本。在Maven的dependencyManagement里统一声明dependencyManagement dependencies dependency groupIdorg.drools/groupId artifactIddrools-bom/artifactId version7.48.0.Final/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement使用BOM管理依赖后子模块里就不用写具体版本号了Maven会统一解析。这个做法能大幅降低多模块项目的版本冲突概率。4.3 MVEL编译时报错注意环境信息有时候控制台会打出类似Unable to load dialect org.drools.compiler.rule.builder.dialect.mvel.MVELDialect的错误说明缺少drools-mvel模块。7.x版本从某个小版本开始把MVEL拆了出去上面的pom.xml里我特意加了这个依赖就是应对这个情况。如果你的项目报错优先检查这个依赖有没有加进来。4.4 性能排查规则多了之后变慢怎么办规则引擎的匹配效率主要看规则数量和事实数量的乘积复杂度。Rete算法通过节点共享来优化但如果你写了大量使用not、exists或递归规则的逻辑性能可能明显下降。这里分享两个实测有效的方向合理拆分KieBase。把无关的规则分散到不同的KieBase里避免一个KieBase拥有全部规则减少匹配节点。尽量避免在规则中使用System.out.println。生产环境里日志量会爆炸建议改为使用SLF4J记录同时规则动作部分尽量轻量只做数据标记不要写太重的业务逻辑。我遇到过规则数量3000条、单次会话插入1000个事实的场景未优化前一次fireAllRules()耗时800毫秒以上。拆分KieBase并把部分规则条件改为带索引字段后耗时至200毫秒以内效果非常明显。4.5 与Spring Boot集成的坑如果你在Spring Boot项目里用Drools通常的做法是把KieContainer声明为Spring单例Bean避免每次调用都重新构建知识库。一个简化的配置类如下Configuration public class DroolsConfig { Bean public KieContainer kieContainer() { KieServices kieServices KieServices.Factory.get(); return kieServices.getKieClasspathContainer(); } Bean public KieSession kieSession(KieContainer kieContainer) { return kieContainer.newKieSession(); } }但注意KieSession不是线程安全的多线程并发使用同一个session会有问题。正确做法是每次操作创建新的session用完dispose()或者使用KIE Server通过远程会话方式执行。把KieSession定义为Bean看似方便实际上在并发场景下是隐患——如果你确实要这么做请确保对session的访问做了同步控制或者使用让Drools 7提供的StatelessKieSession。StatelessKieSession是无状态会话适合一次插入、一批规则、一次性执行结果的场景。改造示例StatelessKieSession session kieContainer.newStatelessKieSession(); session.execute(order);它内部会管理session生命周期是Java Web服务里接入Drools最省心的方式。5. 结合发行包再谈一点部署经验最后再分享一个跟发行包直接相关的经验。如果你要独立部署KIE Server把kie-server.war或business-central.war部署到Tomcat时需要注意几点。首先Tomcat版本建议8.5以上并且要用JDK 8运行时启动其次KIE Server默认的安全配置需要在standalone.xmlWildFly场景或Tomcat的conf/tomcat-users.xml中预置用户角色角色至少包含kie-server否则通过REST API调用时会返回401。我用Tomcat 9部署过KIE Server第一次启动时浪费最多时间的是用户角色配置。KIE Server本身不带默认用户官方文档推荐用WildFly部署但很多企业现有技术栈是Tomcat这时候需要手动配置JAAS或使用KIE Server自带的配置文件。一个小技巧解压war包后在WEB-INF/classes下找到application-users.properties和application-roles.properties直接在这里追加用户名和角色比配置Tomcat全局用户更省事。完整的部署路径是将war包放置到Tomcat的webapps目录启动后访问http://localhost:8080/kie-server/services/rest/server第一次看到返回的json串包含服务器信息就算通了。使用REST客户端调用时需要发送Basic Auth请求头账号就是你配置的kie-server角色的用户。我个人的体会是Drools发行包本身并不复杂真正花时间的永远是规则设计、依赖管理和性能调优这三件事。先从一个小工程跑通Hello World再逐步把业务规则写进.drl比一上来就折腾KIE Server部署要务实得多。你手里这个drools-distribution-7.48.0.Final.zip建议解压后优先看examples里的示例工程那比任何教程都直观。等你把示例跑通了再回来设计自己项目的规则结构思路会清晰很多。本文还有配套的精品资源点击获取
返回列表