惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 聂微东
D
Darknet – Hacking Tools, Hacker News & Cyber Security
P
Privacy International News Feed
NISL@THU
NISL@THU
Know Your Adversary
Know Your Adversary
G
GRAHAM CLULEY
The Hacker News
The Hacker News
P
Privacy & Cybersecurity Law Blog
S
Schneier on Security
T
Troy Hunt's Blog
Attack and Defense Labs
Attack and Defense Labs
S
Secure Thoughts
S
Security Affairs
WordPress大学
WordPress大学
T
Tailwind CSS Blog
博客园 - Franky
T
The Exploit Database - CXSecurity.com
雷峰网
雷峰网
S
SegmentFault 最新的问题
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
P
Proofpoint News Feed
S
Securelist
A
Arctic Wolf
C
Cyber Attacks, Cyber Crime and Cyber Security
有赞技术团队
有赞技术团队
爱范儿
爱范儿
Help Net Security
Help Net Security
Apple Machine Learning Research
Apple Machine Learning Research
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 三生石上(FineUI控件)
C
CERT Recently Published Vulnerability Notes
C
Cisco Blogs
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
Spread Privacy
Spread Privacy
Last Week in AI
Last Week in AI
S
Security @ Cisco Blogs
博客园 - 司徒正美
博客园_首页
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
罗磊的独立博客
博客园 - 叶小钗
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
大猫的无限游戏
大猫的无限游戏
Jina AI
Jina AI
J
Java Code Geeks
T
Threatpost
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
量子位

博客园 - 郭慕荣

彻底搞懂 Codex Skill 与插件:区别、试用、核心作用、项目落地全指南(程序员实战向) Codex Skill 和插件到底有什么区别?程序员如何在项目中落地使用 claudecode 配置防止配置文件泄露总结 Claude code分析外部文件总结 Claude code三种模式详解 hasCompletedOnboarding详解 Claudecode 有哪些常用的命令 claude.md文件详解 claude code 的setting文件详解 Docker部署zookeeper总结 Mac中git ssh的配置(GitLab) Java 类加载机制 面试题(一) 如何监控和调优JVM性能? jvm常用的参数有哪些? 怎么配置? hashmap 和currenthashmap 的原理?详解一下 aop在项目中使用的场景?怎么使用? Java dubbo spring springboot中的spi机制 spring中常见的两种代理模式 Redis的zset 面试汇总 springcloud中常用的注解详解 springcloud中网关gateway总结 spring是怎么解决循环依赖的? MySQL 死锁 怎么处理? 在写left join的时候 是大表在左侧 还是小表在左侧(二) 在写left join的时候 是大表在左侧 还是小表在左侧(一) nacos客户端(接口调用者)如何感知被调用服务下线? (二) nacos客户端(接口调用者)如何感知被调用服务下线?(一) 在MySQL中 redolog undolog binlog 写入的场景,顺序
drools 规则引擎在线化配置
郭慕荣 · 2025-10-23 · via 博客园 - 郭慕荣

在 Drools 规则引擎中实现 “在线化配置” 和 “动态加载”,核心是让规则脱离硬编码,支持通过可视化界面配置并实时生效。以下从实现逻辑、关键技术和具体步骤展开,重点说明是否需要生成 drl 文件及核心实现细节。

结论:不需要生成物理 drl 文件,但需要动态生成 drl 格式的字符串(内存中处理)。

Drools 规则引擎支持多种规则输入形式,包括:

  • 物理 drl 文件(传统方式,需手动编写并打包);
  • 内存中的 drl 字符串(内容与 drl 文件一致,无需落地为文件);
  • 决策表(Excel 格式,适合批量规则);
  • 纯 Java API 构建(通过 RuleBuilder 等类动态创建规则,复杂度高)。

在 “在线化配置” 场景中,动态生成 drl 字符串是最优选择,原因是:

  1. 无需文件 IO 操作,避免磁盘存储、权限、路径管理等问题;
  2. 可通过结构化配置(如数据库存储的规则条件 / 动作)直接拼接为 drl 字符串,转换逻辑简单;
  3. 与 Drools 引擎兼容性最好,drl 语法的灵活性可覆盖绝大多数业务规则场景。

实现分为 5 个核心步骤:规则结构化存储→可视化配置 UI→drl 字符串动态生成→规则动态加载(基于 Drools API)→版本管理与更新。

在线配置的本质是将 “规则逻辑” 拆解为可配置的结构化数据,需定义规则的核心要素(存储在数据库中,如 rule_config 表):

其中,lhs 和 rhs 通常用 JSON 格式存储,方便前端解析和后端转换。

提供给业务人员配置规则的界面,核心功能包括:

  • 事实类型选择:下拉选择规则涉及的 “事实”(Drools 中用于匹配的 Java 实体,如 OrderUser);
  • 条件(LHS)配置:通过表单配置条件(例:选择 Order 的 amount 字段,操作符 >=,值 1000);
  • 动作(RHS)配置:配置满足条件后执行的操作(例:更新 Order 的 discount 字段为 900);
  • 元信息配置:设置优先级、启用状态、版本号等;
  • 规则验证:前端实时校验条件 / 动作的合法性(如字段是否存在、值类型是否匹配)。

配置完成后,数据以结构化形式存入 rule_config 表。

从数据库读取规则配置后,需将其转换为 Drools 可识别的 drl 字符串(内存中生成,不落地)。

示例转换逻辑:假设从数据库读取的规则配置为:

{
  "rule_id": "order_promotion_001",
  "name": "满 1000 减 100 促销规则",
  "priority": 20,
  "enabled": true,
  "lhs": [{"factType":"Order","field":"amount","operator":">=","value":1000}],
  "rhs": [{"action":"UPDATE","factType":"Order","field":"discount","value":900}]
}

转换后的 drl 字符串为:

package com.rules.promotion;  // 自定义包名(用于规则隔离)
import com.model.Order;  // 导入事实类(需与业务实体类路径一致)

rule "order_promotion_001"  // 规则ID
    priority 20  // 优先级
    enabled true  // 是否启用
when  // LHS:匹配条件
    $order : Order(amount >= 1000)  // 绑定Order事实到变量$order
then  // RHS:执行动作
    $order.setDiscount(900);  // 更新折扣字段
    update($order);  // 通知引擎事实已更新(若需触发其他规则)
end

转换代码(核心逻辑):

public String generateDrl(RuleConfig config) {
    

Drools 提供了 Kie API(KieServices、KieFileSystem、KieContainer 等)用于动态管理规则的编译、加载和执行。核心是通过 API 实时构建规则仓库(KieBase),并更新执行会话(KieSession)。

动态加载核心代码:

import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieModule;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;

public class RuleDynamicLoader {
    private final KieServices kieServices = KieServices.Factory.get();
    private KieContainer kieContainer;  

当规则数量较多或频繁更新时,全量重新加载会影响性能,需通过 “版本管理” 和 “增量更新” 优化:

  1. 版本管理:

    • 为每个规则或规则集设置版本号(如 releaseId = group:artifact:version);
    • KieContainer 支持通过 updateToVersion(ReleaseId) 方法切换到新规则版本,避免重复加载不变的规则。
  2. 增量更新:

    • 将规则按业务域拆分(如 “促销规则”“风控规则”),每个域对应一个独立的 KieModule;
    • 仅当某域的规则变化时,重新编译该域的 KieModule 并更新,其他域规则不受影响。
  3. 原子性保证:

    • 规则更新过程中若编译失败,需回滚到上一版本,避免影响现有业务;
    • 可通过 “双容器切换” 实现:新规则加载成功后,再将流量切换到新容器。

在线配置的规则可能存在语法错误(如字段不存在)或逻辑冲突,需在加载前验证:

  • 语法验证:通过 KieBuilder 编译 drl 时,检查是否有错误信息(kieBuilder.getResults().hasMessages(Message.Level.ERROR));
  • 事实类验证:通过反射检查规则中引用的事实类、字段、setter 方法是否存在(例:检查 Order 类是否有 amount 字段和 setDiscount 方法);
  • 逻辑冲突检测:通过规则引擎的 “冲突解决策略”(如优先级)避免规则冲突,或在配置时提示 “与已有规则条件重复”。

Drools 规则引擎的在线化配置与动态加载,核心是 “结构化配置→drl 字符串转换→Kie API 动态加载” 的闭环:

  1. 无需生成物理 drl 文件:通过内存中的 drl 字符串即可驱动规则引擎,避免文件管理问题;
  2. 结构化存储是基础:将规则拆解为条件、动作、元信息,便于 UI 配置和动态转换;
  3. Kie API 是核心:通过 KieFileSystem、KieBuilder、KieContainer 实现规则的编译、加载和更新;
  4. 版本与增量更新是关键:解决大量规则场景下的性能问题,保证更新的安全性。

这种方式让业务规则完全脱离代码,支持实时配置和生效,适合风控、营销、审批等规则频繁变化的业务场景。