# 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启动器
## 什么是规则引擎
- 当我们在对复杂的业务进行开发的时候,程序本身逻辑代码和业务代码`相互嵌套、耦合`,与此同时,`维护成本比较高,可扩展性也比较差`,我们现在想要举一个营销活动的例子,假如双十一活动,针对某些会员(比如白银会员、黄金会员、白金会员)
,每个会员级别可以领取的抵扣券是不一样的,同时每个会员的满减也是不一样的,也就是我们的运营人员在进行活动配置的时候,需要根据不同的条件组合完成响应的逻辑。这些配置是高度灵活、修改是经常发生的,并且每个时间的活动规则都可能不一样,而在活动进行的过程中,不可能随时修改代码,去处理这种动态的数据变更,所以就需要使用规则引擎。
- 总结下来就是:规则引擎是可降低复杂业务逻辑组件复杂性、降低应用程序的维护和可扩展性成本的组件。
- 下面用一张图来表示`**输入输出**`关系

- 我们在`**业务节点**`触发规则引擎的判断,然后对`**规则引擎**`输入`**规则集合簇**`和`**输入参数**`,经过`**规则引擎计算**`,输入`**执行结果**`,然后根据执行结果进行相应的`业务逻辑处理`,这样的话,每个业务节点就可定制业务规则,交给规则引擎去执行判断,然后拿到结果之后判断是否需要执行。
- 那么通过上述的介绍,相信你就可以了解规则引擎的作用了,那么在实际的业务开发中,我们经常会遇到这种场景,就需要规则引擎进行规则定制执行,来满足业务的诉求。
## 设计理念
- 方便运营进行操作,只需页面配置,然后发布,即可动态变更数据。
- 而对于页面的操作,将具备完善的文档,方便快速接入,并且理解配置,使得配置不具备复杂性。
- 可以通过SDK的方式进行接入,支持服务端、客户端通信进行处理。
## 规则引擎要素
### 域
- **域**作为一个业务单元的概念,尤其是在分布式系统中,域可作为原子系统的边界,也可以理解为每个单独的应用,是一个`**业务域**`
- 每个域的数据相互隔离,在进行数据发送的时候,按照域进行加载和发送,之后的所有配置都依托域来进行配置
### 场景
- 域下业务节点,比如淘宝买东西,业务节点有:下单成功、物流通知、收货成功、评价等等,这些都是域中,也就是应用中的业务节点,那么这些业务节点可以称之为**场景**,那么`**域加上场景**`,就确定了一个唯一的业务节点。既然可以确定唯一的业务节点,就可以进行接下来的配置
### 元数据
- 元数据是一些基本的数据,比如常用的,不会经常变更的,其类似于Java中的枚举,是一组数据的集合,用来归类一些通用的配置项
### 操作符
- 操作符即比较符,是一些数学上的概念,比如大于、小于、等于、不等于、包含、不包含,通过操作符,判断左右值,即可判断出当前执行的是否成功,从而判断是否执行下面的节点
### 基础数据
- 基础数据是取值上的概念,通过多种脚本执行引擎,可以通过编写脚本来进行取值,来和目标值进行比较运算
### 数据源
- 数据源,在执行规则判断的时候,可能存在一些计算得到的数据源,并不是仅仅传参,这样就可以动态的组织起始数据
### 策略组
- 策略组是多组策略的集合
### 决策树
- 对策略组进行编排,构建决策树,因为策略组具备多个可能的执行流程分支,执行分支可能是且、或、存在等的关系,通过决策树执行最后的结果,可定义简单返回类型,然后后续业务逻辑会根据返回类型进行决断
## 规则引擎操作页面
- 操作页面按照规则引擎要素进行划分,分为域配置、场景配置、元数据配置、基础数据配置、策略组配置,具体的页面UI等开发完毕之后进行贴图即可
## 规则引擎单节点执行逻辑
- 如下图所示
- 业务节点触发规则执行,执行的时候先判断一些数据的验证逻辑,通过之后才能将数据推到`Rule Engine Calculation`进行执行,在此过程中判断当前业务节点的决策树是否构建完毕,如果构建完毕,则从本地缓存中取出数据,否则重新构建决策树,然后存储到本地缓存执行,最终返回执行结果

## 规则引擎架构设计
- 架构主要分为两个方面,一方面是页面的规则配置,另外一方面是`**仓储(本地缓存)**`的设计
- 页面的操作通过管理员进行操作,然后可选择域进行发布,发布之后就会更新对应域的仓储数据
- 而接入方可以选择使用SDK方式的接入,但是这种接入方式限制了开发语言为Java;也可以使用HTTP接口的方式提供服务
- 通过SDK的方式需要在当前JVM进程加载当前域所在的配置数据;而通过HTTP接口的方式,则会在HTTP服务端加载所有仓储的数据。当然,在更新的时候也是按需更新

## 技术与架构选项
- 存储技术选型: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
- 返回值类型,是否开启返回值,返回值模式