# REC-规则引擎组件 **Repository Path**: sun_hong_yun/rec ## Basic Information - **Project Name**: REC-规则引擎组件 - **Description**: REC(Rule Engine Component)规则引擎组件:提供统一的规则处理方式和策略。支持SDK接入、HTTP接入;只需要进行页面配置即可完成规则的处理,支持简单模式和复杂模式进行编辑。前后端分离项目,可独立部署,也可以前后端打包部署。 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 28 - **Created**: 2022-11-14 - **Last Updated**: 2022-11-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # REC-规则引擎组件 ## 介绍 REC(Rule Engine Component)规则引擎组件:提供统一的规则处理方式和策略。 ## 分支迭代说明 - dev_vue_admin_template:第一个版本 ## 项目模块说明 - rec-admin:后台管理模块 - rec-admin-biz:业务模块 - rec-admin-dal:数据库管理模块 - rec-admin-views:视图模块 - rec-admin-web:对前端接口模块 - rec-common:基础模型、枚举模块等 - rec-core:核心独立部署服务 - 加载所有域进行流程处理,提供Facade接口和MQ的方式进行数据处理 - rec-engine:规则引擎处理器 - rec-engine-rule:规则引擎规则处理 - rec-engine-script:规则引擎脚本处理器 - rec-socket:rec通信管理 - rec-socket-client:rec通信客户端 - rec-socket-server:rec通信服务端 - rec-spring-boot-starter:SpringBoot启动器 ## 什么是规则引擎 - 当我们在对复杂的业务进行开发的时候,程序本身逻辑代码和业务代码`相互嵌套、耦合`,与此同时,`维护成本比较高,可扩展性也比较差`,我们现在想要举一个营销活动的例子,假如双十一活动,针对某些会员(比如白银会员、黄金会员、白金会员) ,每个会员级别可以领取的抵扣券是不一样的,同时每个会员的满减也是不一样的,也就是我们的运营人员在进行活动配置的时候,需要根据不同的条件组合完成响应的逻辑。这些配置是高度灵活、修改是经常发生的,并且每个时间的活动规则都可能不一样,而在活动进行的过程中,不可能随时修改代码,去处理这种动态的数据变更,所以就需要使用规则引擎。 - 总结下来就是:规则引擎是可降低复杂业务逻辑组件复杂性、降低应用程序的维护和可扩展性成本的组件。 - 下面用一张图来表示`**输入输出**`关系 ![image.png](./static/img/rule_engin.png) - 我们在`**业务节点**`触发规则引擎的判断,然后对`**规则引擎**`输入`**规则集合簇**`和`**输入参数**`,经过`**规则引擎计算**`,输入`**执行结果**`,然后根据执行结果进行相应的`业务逻辑处理`,这样的话,每个业务节点就可定制业务规则,交给规则引擎去执行判断,然后拿到结果之后判断是否需要执行。 - 那么通过上述的介绍,相信你就可以了解规则引擎的作用了,那么在实际的业务开发中,我们经常会遇到这种场景,就需要规则引擎进行规则定制执行,来满足业务的诉求。 ## 设计理念 - 方便运营进行操作,只需页面配置,然后发布,即可动态变更数据。 - 而对于页面的操作,将具备完善的文档,方便快速接入,并且理解配置,使得配置不具备复杂性。 - 可以通过SDK的方式进行接入,支持服务端、客户端通信进行处理。 ## 规则引擎要素 ### 域 - **域**作为一个业务单元的概念,尤其是在分布式系统中,域可作为原子系统的边界,也可以理解为每个单独的应用,是一个`**业务域**` - 每个域的数据相互隔离,在进行数据发送的时候,按照域进行加载和发送,之后的所有配置都依托域来进行配置 ### 场景 - 域下业务节点,比如淘宝买东西,业务节点有:下单成功、物流通知、收货成功、评价等等,这些都是域中,也就是应用中的业务节点,那么这些业务节点可以称之为**场景**,那么`**域加上场景**`,就确定了一个唯一的业务节点。既然可以确定唯一的业务节点,就可以进行接下来的配置 ### 元数据 - 元数据是一些基本的数据,比如常用的,不会经常变更的,其类似于Java中的枚举,是一组数据的集合,用来归类一些通用的配置项 ### 操作符 - 操作符即比较符,是一些数学上的概念,比如大于、小于、等于、不等于、包含、不包含,通过操作符,判断左右值,即可判断出当前执行的是否成功,从而判断是否执行下面的节点 ### 基础数据 - 基础数据是取值上的概念,通过多种脚本执行引擎,可以通过编写脚本来进行取值,来和目标值进行比较运算 ### 数据源 - 数据源,在执行规则判断的时候,可能存在一些计算得到的数据源,并不是仅仅传参,这样就可以动态的组织起始数据 ### 策略组 - 策略组是多组策略的集合 ### 决策树 - 对策略组进行编排,构建决策树,因为策略组具备多个可能的执行流程分支,执行分支可能是且、或、存在等的关系,通过决策树执行最后的结果,可定义简单返回类型,然后后续业务逻辑会根据返回类型进行决断 ## 规则引擎操作页面 - 操作页面按照规则引擎要素进行划分,分为域配置、场景配置、元数据配置、基础数据配置、策略组配置,具体的页面UI等开发完毕之后进行贴图即可 ## 规则引擎单节点执行逻辑 - 如下图所示 - 业务节点触发规则执行,执行的时候先判断一些数据的验证逻辑,通过之后才能将数据推到`Rule Engine Calculation`进行执行,在此过程中判断当前业务节点的决策树是否构建完毕,如果构建完毕,则从本地缓存中取出数据,否则重新构建决策树,然后存储到本地缓存执行,最终返回执行结果 ![image.png](./static/img/rule_engin_process.png) ## 规则引擎架构设计 - 架构主要分为两个方面,一方面是页面的规则配置,另外一方面是`**仓储(本地缓存)**`的设计 - 页面的操作通过管理员进行操作,然后可选择域进行发布,发布之后就会更新对应域的仓储数据 - 而接入方可以选择使用SDK方式的接入,但是这种接入方式限制了开发语言为Java;也可以使用HTTP接口的方式提供服务 - 通过SDK的方式需要在当前JVM进程加载当前域所在的配置数据;而通过HTTP接口的方式,则会在HTTP服务端加载所有仓储的数据。当然,在更新的时候也是按需更新 ![image.png](./static/img/rule_engin_all.png) ## 技术与架构选项 - 存储技术选型:MongoDB,因为是一些配置的数据,有一些的数据可能经常的发生改动,使用MySQL不方便经常的变更数据,因此使用文档数据库MongoDB - 开发框架:SpringBoot、Vue2.0、Netty4.x、Vue-Template-Admin - 数据请求:OKHTTP - 其他暂无 ## 数据表设计 - 数据表设计,根据规则引擎要素可以发现聚合了6张表,实际上域和场景应该是绑定到一起的,可以合并,也可以考虑分开,此处选择分开存储 - 在数据设计的过程中,有些数据是固化的,每6张表数据都有的,如下表,因此这些字段不再单独列出,具体的可在存储的数据结构中看到 | **字段名称** | **类型** | **备注** | | --- | --- | --- | | id | object(String) | mongodb 自带id | | uuid | String | 雪花算法随机UUID | | desc | String | 功能描述 | | createTime | Date | 创建时间 | | updateTime | Date | 更新时间 | | isDelete | int | 状态 1有效,0无效 | | env | String | 环境 | - 域数据存储设计(文档名称:rec-domain) | **字段名称** | **类型** | **备注** | | --- | --- | --- | | domainName | String | 域名称 | | domainCode | String | 域Code | - 域场景(文档名称:rec-scene) | **字段名称** | **类型** | **备注** | | --- | --- | --- | | domainCode | String | 域Code | | scenePairs | List | 场景对 | - 元数据(文档名称:rec-metadata) | **字段名称** | **类型** | **备注** | | --- | --- | --- | | domainCode | String | 域Code | | metadataName | String | 元数据名称 | | metadataList | String(JSON格式) | 元数据枚举值 | - 基础数据(文档名称:rec-basedata) | **字段名称** | **类型** | **备注** | | --- | --- | --- | | domainCode | String | 域Code | | fieldName | String | 基础数据名称 | | dataType | String | 数据类型(布尔、字符串、数值、日期、元数据等) | | scriptType | String | 脚本执行类型 | | scriptContent | String | 脚本内容 | | resultType | String | 脚本执行返回类型(只能是基本数据类型) | - 数据源(文档名称:rec-dataSource) | **字段名称** | **类型** | **备注** | | --- | --- | --- | | dataSourceName | String | 数据源名称 | | dataSourceCode | String | 数据源Code | | dataSourceType | String | 数据源类型(脚本、HTTP、SQL) | | scriptInfo | Object | 数据源为脚本的执行数据集 | | httpInfo | Object | 数据源为HTTP的执行数据集 | | sqlInfo | Object | 数据源为SQL的执行数据集 | - 策略组(文档名称:rec-strategy) | **字段名称** | **类型** | **备注** | | --- | --- | --- | | domainCode | String | 域Code | | sceneCode | String | 场景Code | | strategyName | String | 策略组名称 | | dataSourceType | String | 数据源类型(脚本、接口、SQL) | | dataSourceCode | String | 数据源关联Code | | ruleType | String | 规则配置类型(默认为List) | | ruleListInfo | Object | 规则配置类型为List时候的规则数据 | | ruleTreeInfo | Object | 规则配置类型为Tree时候的规则数据 | ## 项目地址 - [https://gitee.com/icanci/rec](https://gitee.com/icanci/rec) - 分支: dev_vue_admin_template ## 迭代版本 - 初步设计如上 - 第一个版本暂不考虑客户端和服务端的开发 ## 开发备注 - MongoDB启动:mongod --dbpath /usr/local/var/mongodb --logpath /usr/local/var/log/mongodb/mongo.log --fork - MongoDB关闭: ## 启动项目 - 更改MongoDB链接配置,并且建立MongoDB数据库:rec - 执行打包命令:mvn clean install - 主方法运行:AdminViewApplication - 浏览器访问:http://localhost:9999/#/login 登录即可 ## TODO - 新建模块实现服务的运行:加载所有域的信息进行处理 rec-support,定义SPI加载接口,SDK和rec-core的实现不一致,取值方式不一致 - rec-register:注册中心 - rec-group:组的概念SAAS - 返回值类型,是否开启返回值,返回值模式