diff --git a/预研项目/imgs/规则引擎/image-20210616140457382.png b/预研项目/imgs/规则引擎/image-20210616140457382.png new file mode 100644 index 0000000..b83f2a2 Binary files /dev/null and b/预研项目/imgs/规则引擎/image-20210616140457382.png differ diff --git a/预研项目/imgs/规则引擎/image-20210616160110681.png b/预研项目/imgs/规则引擎/image-20210616160110681.png new file mode 100644 index 0000000..e91bb84 Binary files /dev/null and b/预研项目/imgs/规则引擎/image-20210616160110681.png differ diff --git a/预研项目/规则引擎.md b/预研项目/规则引擎.md new file mode 100644 index 0000000..5b0967b --- /dev/null +++ b/预研项目/规则引擎.md @@ -0,0 +1,280 @@ +# 规则引擎 + +实现业务和代码的分离,即把业务逻辑抽离,实现规则和系统的解耦。 数据输入-> 业务规则解释 -> 做出业务决策。 + +适用于复杂、多变的业务场景。 + +`原先一堆 case 的逻辑,改由规则引擎控制,对频繁修改的业务规则提高修改效率` + +### [Drools](https://github.com/kiegroup/drools) + +Drools是一个基于Java的**开源**规则引擎。 + +Drools 是用 Java 语言编写的开放源码规则引擎,使用 Rete 算法对所编写的规则求值。Drools 允许使用声明方式表达业务逻辑。可以使用非 XML 的本地语言编写规则,从而便于学习和理解。并且,还可以将 Java 代码直接嵌入到规则文件中,这令 Drools 的学习更加吸引人。 + +`ksession-rules.drl` + +```yaml +package com.rules +import model.ProtocolType +dialect "java" + +rule "jk16" + when + $protocol : ProtocolType(data matches "^1A12.*$" ) + then + $protocol.setType("xx燃气表协议"); + System.out.println("触发规则1:"+$protocol.getData()); + end + +rule "jkstd" + no-loop true + lock-on-active true + salience 1 + when + $protocol : ProtocolType(data matches "18.*",length == 10) + then + $protocol.setType("xx水表标准协议"); + System.out.println("触发规则2:"+$protocol.getData()); + end +``` + +`main.java` + +```java +public static void main(String[] args) { + KieServices ks = KieServices.Factory.get(); + KieContainer kContainer = ks.getKieClasspathContainer(); + KieSession kSession = kContainer.newKieSession("ksession-rules"); + + ProtocolType pt = new ProtocolType(); + pt.setData("1A122312345"); + + kSession.insert(pt); + kSession.fireAllRules(); + kSession.dispose(); + System.out.println(pt); +} +``` + + + +### Ilog JRules + +Ilog Jrules是完整的业务规则管理系统(BRMS),它提供了对整个企业业务规则进行建模、编写、测试、部署和维护所必需的所有工具。 + + + +### Easy Rules + +[Github](https://github.com/EasyRules/easyrules.git) + ++ 轻量级 简单易用的API ++ 基于POJO 注解开发模型 ++ 通过高效的抽象来定义业务规则并轻松应用它们 ++ 支持创建复合规则 ++ 支持通过表达式语句创建规则(MVEL,SpEL,JEXL等) + +scala改写官方start: + +```scala +object main { + + def main(args: Array[String]): Unit = { + println("hello rule engine") + + val rule = new MyRule() + rule.bRain = true + val ruleEngine = RulesEngineBuilder.aNewRulesEngine().build() + ruleEngine.registerRule(rule) + + ruleEngine.fireRules() + } +} + +@Rule(name = "my rule", description = "test rule") +class MyRule() { + var bRain = false + + @Condition + def itRains(): Boolean = { + bRain + } + + @Action + def doSomething(): Unit = { + println("it rains") + } +} +``` + +在最新版本中才支持表达式语句创建 + +下载git代码并mvn install后本地库使用 + +```xml + + + org.jeasy + easy-rules-core + 4.1.1-SNAPSHOT + + + + org.jeasy + easy-rules-mvel + 4.1.1-SNAPSHOT + + +``` + +`weather-rule.yml` + +```yml +name: "weather rule" +description: "if it rains then take an umbrella" +condition: "rain == true" +actions: + - "System.out.println(\"It rains, take an umbrella!\");" +``` + + + +```scala +def main(args: Array[String]): Unit = { + val ruleFactory = new MVELRuleFactory(new YamlRuleDefinitionReader) + val source = Source.fromInputStream(getClass.getResourceAsStream("/weather-rule.yml")) + val weatherRule = ruleFactory.createRule(source.bufferedReader()) + source.close() + + val facts = new Facts() + facts.put("rain", true) + + val rules = new Rules() + rules.register(weatherRule) + + val rulesEngine = new DefaultRulesEngine() + rulesEngine.fire(rules, facts) +} +``` + +构想的一个应用场景: + +[代码](https://github.com/yinweiwen/easy-rules-scala-example) + +根据测点属性或数据,来判断需要执行哪些操作: + +```scala +def handle(data: StationData): Unit = { + val facts = new Facts() + facts.put("sensor", BoxData(data)) + + engine.fire(rules, facts) +} + +// 需要把待处理数据进行封装 +// like a POJO +case class BoxData(var data: StationData) { + def validate(): Unit = { + data = Validator.handle(data) + } + + def analyze(): Unit = { + data = Analyzer.handle(data) + } + + def storage(): Unit = { + Storage.handle(data) + } +} +``` + +构造规则:例如温度超过30时执行指定过滤和分析操作。 +```yaml +name: "sensor rule" +description: "sensor handle rule" +condition: "sensor.data.v(\"temperature\")>30" +condition: "true" +actions: + - "System.out.println(sensor);" + - "sensor.validate();" + - "sensor.analyze();" +``` + + + +### [Node-Red](https://nodered.org/) + +__Low-code programming for event-driven applications__ + +[**概念**](https://nodered.org/docs/user-guide/) + +`Node` 节点 、`Flow` 流程 、Workspace 工作区间、Subflow 子流程、Sidebar 侧边栏、Palette调色板、Wire连接线 + +**安装** + +```shell +#windows +npm install --global --production windows-build-tools + +npm install -g --unsafe-perm node-red + +http://localhost:1880/ +``` + +%user%\\.node-red\settings.js + +```js +adminAuth: { + type: "credentials", + users: [{ + username: "admin", + password: "$2a$10$DFRjJdlRX/wEw3C.qyEdW.UyOGlPkGv8lbyZnuh6XX/4RVSQS.ZgO", // bcrypt随机带盐加密 + permissions: "*" // read write + }], + sessionExpiryTime: 86400, +}, +``` + +First Flow: Inject->Function->Debug + +![image-20210616140457382](imgs/规则引擎/image-20210616140457382.png) + +Second Flow: + +安心云数据处理 + + + +安心云的上报流程 + +![image-20210616160110681](imgs/规则引擎/image-20210616160110681.png) + +总结**一般**的推送流程: + +Kafka消费ET处理后的测点数据 --> 过滤结构物、监测因素 --> 构造发送消息结构体 --> 网络请求(http/tcp...) + +> 通过这种方式可以实现简单的数据上报功能, +> +> 1. 可视化配置,灵活高效 +> 2. 可开放作为平台功能的一部分,让有一定开发能力的客户直接使用。 +> 3. 可以匹配大多数接入方式场景 +> +> 主要存在的缺陷: +> +> 1. 每个项目独立启动一个Kafka-consumer消费者,性能浪费 +> 2. 状态数据没法处理(计算变化量等情况) +> 3. “函数”节点中纯js代码不支持Redis/Db等操作 +> 4. 自带的HTTP请求node较简单,不支持参数头设置。 +> 5. 请求返回校验和日志记录问题 +> 6. 不支持的场景:数据库直接写入、webservice接入等 +> 7. 自定义node仅支持Node.js语言 + +综上:只能实现逻辑较为简单的一些上报,可作为平台扩展功能一部分。大多数针对项目的上报,存在后处理逻辑,目前只能通过硬编码的方式实现。 + + + +EI 边缘计算 + +低时延、大带宽、大连接、本地化 +