分享好友 最新动态首页 最新动态分类 切换频道
规则引擎的架构设计与系统实现
2024-12-27 21:17

GitHub - failgoddess/rule: 规则引擎

业务规则、配置化编程、政策引擎、规则引擎

目录

ruleEngine

1. 背景

2. 方案考察

2.1. 硬编码

2.2. Drools

2.3. Urule

2.4. 自研规则引擎

3. 能力要求

4. 名词解释

5. 概要设计

5.1. 功能模块划分

5.1.1. 公式推理器Calculator

5.1.2. 指标解析器FormulaExecuter:

5.1.3. 动作执行器ActionExecuter

5.1.4. 模型执行器RuleModel

5.1.5. 模型构建器RuleModelBuilder

5.1.6. 模型加载器RuleModelLoader

5.1.7. 交互转换器

5.2. 系统设计

5.2.1. 指标占位符

5.2.2. JSON出参解析

5.2.3. 关系运算符

5.2.4. 技术选型

5.3. 关键技术说明

5.3.1. 逻辑式编程

5.3.2. 分治策略

5.3.3. 决策树

5.3.4. 括号匹配算法

6. 详细设计

6.1. 数据模型

6.1.1. 规则ER-图

6.1.2. 关系数据库表结构

6.2. 执行逻辑图

6.2.1. 规则执行时序图

6.2.2. 指标解析执行流程

6.3. 缓存对象数据结构

6.4. 枚举值配置


在项目步入成熟期,规则类需求几乎占据了业务所有需求的半边天。一方面规则唯一不变的是“多变”,另一方面开发团队对“规则开发”的感受是乏味、疲惫和缺乏技术含量。如何解决规则开发的效率问题,最大化解放开发团队成为一个新的挑战。

规则底层采用规则引擎来实现。规则引擎是一种嵌入在应用程序中的组件,实现了将业务规则从应用程序代码中分离出来,并使用预定义的规则语义来编写业务规则。规则引擎接受数据输入,解释业务规则,并根据规则执行相应的业务逻辑。一个业务规则包含一组条件和在此条件下执行的操作,它们表示业务规则应用程序的一段业务逻辑。我们在业务中设置一个或者多个条件,当满足这些条件时触发相应的操作,规则引擎设计的初衷是可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件或者数据库中,使得规则的变更不需要修改代码即可使用,做到最大程度的灵活。

现在市面上在做业务规则的过程中有多种实现方案

优点

稳定性较佳:语法级别错误不会出现,由编译系统保证。

当规则较少、变动不频繁时,开发效率最高。

缺点

规则迭代成本高:对规则的少量改动就需要走全流程(开发、测试、部署)。

规则开发和维护门槛高:规则对业务分析人员不可见。业务分析人员有规则变更需求后无法自助完成开发,需要由开发人员介入开发。

优点

策略规则和执行逻辑解耦方便维护。

缺点

业务分析师无法独立完成规则配置:由于规则主体DSL是编程语言(支持Java, Groovy, Python,因此仍然需要开发工程师维护。

规则的语法仅适合扁平的规则,对于嵌套条件语义(then里嵌套when...then子句)的规则只能将条件进行笛卡尔积组合以后进行配置,不利于维护。

优点

可视化操作完善、功能强大

缺点

不支持回溯:当前分支没有符合条件的之后不支持回溯

不支持动态加载数据:例如门店有等级、店龄、区域等若干属性,业务规则具体是根据店龄不同给出结果还是根据等级,属于规则的业务范畴,调用方并不关心。要是每次需要将所有可能用于规则判断的数据全部由调用方传入,无疑降低了规则的灵活性。

在学习机器学习中决策树的算法时可以生成决策树的决策流图。决策树整体分为两个阶段:通过算法计算找出规律将规律构建决策模型、传入新数据基于决策流进行新的决策分析。这一点给我带来了很大的思想启发,配置规则的过程作为决策树的构建阶段,新数据决策为决策树的预测过程。出现多个决策路径组合的为最终结果的场景也可以理解决策森林算法的演化。

规则引擎的设计主要分为两部分:一部分是规则的维护,包括规则的创建、修改、删除;一部分是规则的执行。规则的维护部分侧重点是页面,我们需要将用户在页面上的操作转换为内置规则并保存到数据库中。在规则执行的过程中调用方只需要选择规则传入相应的数据即可获得决策结果。结合整体需求,规则引擎应该有可扩展、易维护的特点,先将规则引擎的功能需要实现的功能点总结如下

指标部分(维护指标、计算执行指标

模型维护(模型即实体,包括模型的创建以及模型属性的维护

规则维护(包括对规则的增删改查

条件维护(对规则条件的增删改查

指标维护(对规则指标的增删改查

结果维护(对规则结果的增删改查

节点维护(包括静态节点和动态节点部分

基于规则版本的决策记录(基于历史规则查看判定过程记录

规则的版本控制

根据技术考察和能力要求对我们的规则引擎提出了更为全面的要求

l 支持可视化的界面配置

l 支持嵌套条件语义

l 支持组合条件

l 支持动态加载

l 支持决策日志

l 支持规则历史版本

l 支持回溯

l 支持决策森林

术语及缩略语名词解释规则每一个需要用于判定的业务场景就是一套规则,例如:可否邮寄判断;规则通常由每一个决策树的判定结果和操作符构成,例如:区域决策树AND(调整价决策树OR年份决策树);规则的本质是分类问题,由决策树和操作符构建的决策森林节点每一个规则内可能影响决策判定流程和结果的一个影响因素(维度)结果一个规则中所有决策树中可能返回的结果,也就是一个决策树数的叶子结点,例如:可否邮寄判断的结果集合是是和否决策树决策树又称为判定树,是规则中的每一条判定路径,这个判定路径是根据不同节点以及条件执行不同分支路径,完整的判定路径分支、节点就是一棵决策树。考虑到不同连接接有同一个下一跳的情况决策树也被称为决策图操作符条件运算符分支一个分支包含多个连接是一组连接的集合。条件条件由被比较值、操作符、比较值构成。名称参考12/6=2 被除数、除数、商连接连接表示当前分支中一个节点在一组条件下要进入的下一跳,下一跳可以是另外一个连接也可以是结果。主要是达到执行对象切换的作用。同一个分支中的不同连接指向同过个下一跳逻辑关系为或的关系,同一个连接中不同的条件为且的关系。指标是规则流程执行中的元数据。判定日志每一次判定结果的日志记录判定数据用于规则判定时的入参对象历史规则规则的历史版本控制,每一次规则的修改都会引起一个版本变化,同一时间节点一个规则只会有一个生效的版本

5.1.1. 公式推理器Calculator

用于计算公式例如((18)/9)9572>1008611计算,是指标解析器的底层实现,公式推理器一部分基于规则引擎实现、一部分基于手写运算符计算器实现

5.1.2. 指标解析器FormulaExecuter:

在公式类指标中用于公式的构建例如:目标库存为公式类指标,计算公式为平均周销*周数,由指标解析器将平均周销和周数替换成指定的数值

在传入类指标中用于将调用方的输入值转化成指标项例如目标库存中周数指标

在配置类指标中用于将配置到系统中的参数解析成指定指标

在动作类指标中用于组件构造动作执行器的执行入参并调用动作执行器。

5.1.3. 动作执行器ActionExecuter

根据动作的类型传入参执行方法或者发送相应的请求,并负责解析返回值;不变型动作的执行可基于动作执行历史记录

5.1.4. 模型执行器RuleModel

负责解析规则模型按照深度优先的规则执行决策树,流程树

5.1.5. 模型构建器RuleModelBuilder

确定一个规则编码负责从数据表中将于这个规则相关的数据加载到程序中,并组装出可以用于执行的规则模型JSON

5.1.6. 模型加载器RuleModelLoader

负责加载配置好的模型,规则当前版本的加载优先级为Cache —> Redis —>模型构建器,规则历史版本的模型直接加载历史版本中的模型JSON

5.1.7. 交互转换器

前端页面本着页面友好的原则会采用多种类型的页面展示和实现,前端数据和后端模型的数据会差异比较大所以在前后交互的过程中采用交互转换器进行数据转换,每种样式的展示方式都会有一个相应的转换器。

5.2.1. 指标占位符

${123}:调用id为123的指标

@{storeCode}:引用入参storeCode的实际值

%{ now()}:系统内置函数的返回值,这个系统特指规则引擎内部

#{123}:引用id为123的节点

["storeCode","1002"]  向被调用者传入参数storeCode为1002 

5.2.2. JSON出参解析

请求型指标会访问一个url发送请求获得非接口返回值是JSON形式的数据,这里采用JsonPath插件对JSON进行解析获取需要的数据。完整语法请参考JsonPath官方文档

Map或对象:$.attr_name

List< Map或对象>$. data[i]. attr_name

i=*或者不配表示 取全部列表每一个item的attr_name逗号隔开

i=5 代表取索引为5 的attr_name

5.2.3. 关系运算符

系统内置操作符用于经销规则的逻辑判断,系统内置的每一条指令都有一个操作符,它表示该指令应进行什么性质的操作。不同的指令用操作符这个字段的不同编码来表示,每一种编码代表一种指令。

操作符布尔不区分字符串字符串数值时间列表be介于(闭区间)√√bed介于(开区间)√√nbe不介于(闭区间)√√nbed不介于(开区间)√√cn包含√ncn不包含√en为空√√√√√√nn不为空√√√√√√eq等于√√√√√√eqd等于(不区分)√√neq不等于√√√√√√neqd不等于(不区分)√√ge大于等于√√gt大于√√in在集合√nin不在集合√le小于等于√√lt小于√√nre不正则√√re正则√√and并且√√√or或√√√not非√√√xor异或√√√lp左括号rp右括号add加√√sub减√√mul乘√div除√acm取余√

5.2.4. 技术选型

技术选型目前规则引擎领域开源的主要有Drools、IKExpression、Aviator、QLExpress、SimpleEL、Groovy、Fel等,鉴于Fel表达式求值语法简洁。同时其优异的性能表现,规则中心选型Fel。执行100 万次表达式求值的性能表现对比如下图

本系统会用到:依赖性任务排序的算法(用于指标依赖执行顺序的执行顺序)、决策树算法、分治策略、括号匹配、策略模式、逻辑式编程、JSONPath、DFS算法、Cache、Fel。

5.3.1. 逻辑式编程

算法+数据结构=程序这是Pascal设计者Niklaus Wirth的一本著作的书名,它刻画了过程式尤其是结构化编程的思想。后来Robert Kowalski进一步提出:算法=逻辑+控制。其中逻辑是算法的核心,控制主要用于改进算法的效率。在逻辑式编程中,程序员只需表达逻辑,而控制交给编程语言的解释器或编译器去管理。

本规则引擎采用逻辑式编程的思想,由业务人员提供业务规则,开发负责将业务规则整理转义成解释器可解释执行的配置文件,在交由解释器和编译器解析执行。则可以做到业务只考虑规则构建、开发需表达逻辑、而执行交给解释器或编译器去管理,当调用方选择规则模型传入初始化数据后有加载器加载指定模型、执行器用相关的决策路径来控制执行返回规则结果达到一部分业务流程可配置的目的。

5.3.2. 分治策略

经销规则模块执行器采用分治策略实现深度遍历的决策树。分治策略是对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。

分治法的基本步骤 分治法在每一层递归上都有三个步骤

分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题

解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题

合并:将各个子问题的解合并为原问题的解。

5.3.3. 决策树

决策树机器学习预测方法,主要用于对离散型数据的分类。一个值经过相应的节点测验会跳过假分支进入真分支,所以一组值经过决策树以后,就会形成从树跟到结果节点的一条唯一路径。所以它除了可以对输入进行分类之外,还能给出如此分类的解释。算法实现分为:特征选择、决策树的训练构建决策模型、模型对新数据测预测

规则引擎的数据维度抽取参考特征选择,也是在硬编码中用于if判断的数据字段;决策树模型的构建采用业务人员在实际工作中的经验规则;传入数据由模型执行类比对模型预测的阶段

5.3.4. 括号匹配算法

指标的公式是可以嵌套的所以需要来解析公式需要用到括号匹配算法

123 门店平均销量指标 入参门店编码 sku编码 天数

456 门店可用库存指标 入参门店编码 sku编码

789 门店需求量指标公式为:门店10天的sku需求量=10天门店最近30天平均该sku销量-门店前库存;可表示为 10${123(storeCode:@{storeCode},skuCode:@{skuCode},dayNumber:30)}-${345(storeCode:@{storeCode},skuCode:@{skuCode})}

这个解析的过程是一个采用分治策略的递归解析过程;用到括号匹配算法来解析公式

原括号匹配算法只是在结构出判断堆栈是否为空用于判断是否成对出现,这里需要做一个改造每一次堆栈为空的时候表示这是一个最大单元也就是整个公式最多可以分为几段 门店需求量就可以分为两段 ${123(storeCode:@{storeCode},skuCode:@{skuCode},dayNumber:30)}和${345(storeCode:@{storeCode},skuCode:@{skuCode})}

在利用分治递归的思想将每一段分别处理

6.1.1. 规则ER-图

6.1.2. 关系数据库表结构

节点表

字段数据类型长度说明Idint864节点表rule_idint864所属规则IDNamevarchar64节点标题note_typeint432节点数据来源类型:10传入20指标值note_categoryint432节点类型:1可变、0不可变Attributevarchar128判定数据对象的字段note_categoryint432节点类型:1可变、0不可变value_typeint43210数字20时间30字符串35不区分字符串40列表parametervarchar255参数用json表示,节点调用指标的参数只能是配置好的固定值或者传入节点的数据值quota_idint864指标idRemarkvarchar512备注

结果表

字段数据类型长度说明Idint864结果表rule_idint864所属规则IDNamevarchar64结果标题Datavarchar128结果数据result_typeint432结果类型10固定值20节点值30指标值node_idint864节点IDquota_idint864指标IDparametervarchar255参数用json表示Remarkvarchar512备注

规则表

字段数据类型长度说明Idint864规则表Namevarchar64规则名称Codevarchar64规则编码Contentvarchar32规则内容data_typevarchar32结果数据的类型node_infovarchar32支持的对象节点的描述node_attributevarchar32支持的对象节点的属性Remarkvarchar255备注

决策树表

字段数据类型长度说明Idint864经销商商品授权表rule_idint864规则IDcodevarchar64决策树编码first_branch_idint864第一跳ID(分支)namevarchar64决策树标题remarkvarchar255备注

运算符表

字段数据类型长度说明idint864运算符表codevarchar64编码operation_typeint432类型:1关系运算符2逻辑运算符3优先级运算符4算数运算符namevarchar128运算符标题remarkvarchar255备注

分支表

字段数据类型长度说明idint864分支表node_idint864节点IDnode_typeint864节点数据类型namevarchar64条件名称operation_idint864操作符IDthresholdvarchar32阀值rule_idint864规则IDtree_idint864决策树IDremarkvarchar512备注

条件表

字段数据类型长度说明idint864条件表link_idint864连接IDpriorityInt464优先级namevarchar64条件名称operation_idint864操作符IDthresholdvarchar32阀值rule_idint864规则IDbranch_idint864分支IDthreshold_typeInt432阀值类型10固定值20节点值note_idint864节点IDremarkvarchar512备注

连接表

字段数据类型长度说明idint864连接表namevarchar64连接名称priorityint464优先级tree_idint864决策树IDbranch_idint864所属分支IDnext_branch_idint864下一跳分支IDnext_typeint432下一跳类型next_result_idint864下一跳结果IDrule_idint864规则IDremarkvarchar512备注

判定数据表

字段数据类型长度说明idint864判定数据表rule_idint864规则IDrule_versionvarchar128规则版本号datavarchar128判定数据resultvarchar64结果(不一定来源于结果)result_idint864结果ID(为空则表示规则结果为和合成结果)history_idint864历史IDfactorvarchar128决定因素remarkvarchar512备注

判定日志表

字段数据类型长度说明idint864判定数据表rule_idint864规则IDrule_versionvarchar128规则版本号judge_data_idint864判定数据IDflagbool0是否符合history_idint864历史IDnode_idint864节点IDlink_idint864连接IDcondition_idint864条件IDbranch_idint864分支IDremarkvarchar512备注

历史规则表

字段数据类型长度说明idint864历史规则表rule_idint864规则IDrule_versionvarchar128规则版本号start_timetimestamp64开始时间end_timetimestamp64结束时间remarkvarchar512备注

指标表

字段数据类型长度说明idint864配置表quota_typeint432指标类型10方法类20请求类30公式类40配置类namevarchar255指标名称value_typeint432数据值类型10数字20时间30字符串35不区分字符串40列表java_methodvarchar25510方法类所配置的方法request_urlvarchar25520请求类请求路径request_methodVarchar25520请求类请求方法,目前只支持get、postformulaVarchar25530公式类计算公式deployVarchar25540配置类配置parameterVarchar255参数用json表示feedback_ruleVarchar255返回值取值规则necessaryvarchar255必须的入参也就是调用者必传的字段cache_imevarchar255请求型缓存时间remarkvarchar512备注

6.2.1. 规则执行时序图

6.2.2. 指标解析执行流程

6.2.2.1. 公式型指标

10*${123(attr1:12,attr2:${456})}+2

10*

${123(attr1:12,attr2:${456})}

123 的指标

解析123指标需要的入参

attr1=12

attr2=${456}

${456}

456 的指标

456 的指标 执行

123入参构建完成

123 的指标 执行

+2

6.2.2.2. 请求型指标

枚举类型枚举值枚举描述节点数据来源类型10传入值20指标值指标类型10方法类20请求类30公式类40配置类结果类型10固定值20节点值30指标值下一跳类型1分支2结果阀值类型10固定值20节点值数据值类型10数值20时间30字符串35不区分大小字符串40列表
最新文章
[2025福建公务员三明进面分数线汇总]福建省考大田县市场监督管理局往年招录情况及报名人数统计分析
  广东人事考试网同步中国公务员考试网信息:[2025福建公务员三明进面分数线汇总]福建省考大田县市场监督管理局往年招录情况及报名人数统计分析,更多关于2025福建公务员三明进面分数线汇总,福建省考大田县市场监督管理局招录情况,广东人
男科热点:沈阳正规男科医院“总榜排名”沈阳早泄治疗好医院是哪家?
  男性朋友的评价是对医院的肯定,所以在选择医院的时候,患者要看到医院在患者心中的位置,选择评价好的、被人们信任的医院进行治疗。  1.经过多年的实践,医院形成了一套疾病的治疗体系,并在治疗过程中更新了原有的医疗技术。辽宁附
网站排名优化之如何挖掘关键词
一个网站如果不注意网站排名优化的问题,渐渐的肯定是会影响到自然排名,一个排名不好的网站,网站的流量以及带来的推广宣传效果同样会不好,网站权重也会受到影响。在整体的网站优化中,关键词的优化是十分重要的,那伯乐网络传媒结合自己
谷歌SEO中,搜索友好的网站是啥样,你知道吗?
在我多年的SEO实战经验中,我深刻体会到,一个对谷歌搜索引擎友好的网站,是提升网站排名、获取精准流量的关键。无论是企业官网还是电商平台,都需要在谷歌SEO上下足功夫,才能在这片竞争激烈的互联网海洋中脱颖而出。今天,我将从多个角度
潜行游戏哪些人气高 高人气潜行游戏排行
探寻游戏世界中的隐形高手,潜行类游戏爱好者们总在寻找那份刺激与策略的完美结合。本文将揭示高人气潜行游戏排行榜,带你领略那些深入人心、技巧与剧情并重的游戏杰作,无论是硬核玩家还是新手探索者,都能在这里找到属于自己的冒险之旅。
经典erp系统界面在哪打开的 经典erp系统界面在哪打开?全面解析入口
经典系统界面在哪打开?全面解析入口经典ERP系统界面可以通过以下几种方式打开:1、直接通过ERP系统提供的客户端进行访问;2、使用ERP系统的Web端口进入;3、通过企业内部的门户网站进行访问。下面将详细介绍每种方式的具体操作步骤和注意
店铺宣传推广的 今年Zui新攻略
店铺宣传推广的今年Zui新攻略在当今竞争激烈的电商行业中,如何通过有效的推广策略脱颖而出,成为每个店铺都关心的问题。竞价开户和电商平台开户成为了提升店铺曝光度和销售额的关键环节。在本文中,我们将为您详细介绍竞价开户的流程和注
金华进口樱桃汁国外工厂备案代理Good Service
金华进口樱桃汁国外工厂备案代理——众多客户见证——选择卓鹰进口清关,就是靠谱!卓鹰百科知识分享:樱桃(学名:Cerasus pseudocerasus),是某些李属类植物的统称,包括樱桃亚属、酸樱桃亚属、桂樱亚属等。乔木,高2-6米,树皮灰白色。
山东省济南较好的职业学校-报名电话
春蚕一生没说过自诩的话,那吐出的银丝就是丈量生命价值的尺子。敬爱的老师,您从未在别人面前炫耀过,但那盛开的桃李,就是对您最高的评价。仅供参考,如果觉得很不错,欢迎大家咨询!济南应用技术职业中等专业学校开设有针对性强、适应市
用AI轻松生成高清美女写真,这款工具你一定要试试!
限时免费,点击体验最近超火的AI生图神器,坐拥3000美女的大男主就是你! https://ai.sohu.com/pc/generate/textToImg?_trans_=030001_yljdaimn 在这个数字时代,AI技术不断进步,各种与我们生活息息相关的领域都在发生着翻天覆地的变化。
相关文章
推荐文章
发表评论
0评