You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

7.0 KiB

规则引擎

实现业务和代码的分离,即把业务逻辑抽离,实现规则和系统的解耦。 数据输入-> 业务规则解释 -> 做出业务决策。

适用于复杂、多变的业务场景。

原先一堆 case 的逻辑,改由规则引擎控制,对频繁修改的业务规则提高修改效率

Drools

Drools是一个基于Java的开源规则引擎。

Drools 是用 Java 语言编写的开放源码规则引擎,使用 Rete 算法对所编写的规则求值。Drools 允许使用声明方式表达业务逻辑。可以使用非 XML 的本地语言编写规则,从而便于学习和理解。并且,还可以将 Java 代码直接嵌入到规则文件中,这令 Drools 的学习更加吸引人。

ksession-rules.drl

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

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

  • 轻量级 简单易用的API
  • 基于POJO 注解开发模型
  • 通过高效的抽象来定义业务规则并轻松应用它们
  • 支持创建复合规则
  • 支持通过表达式语句创建规则(MVEL,SpEL,JEXL等)

scala改写官方start:

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后本地库使用

<dependencies>
    <dependency>
        <groupId>org.jeasy</groupId>
        <artifactId>easy-rules-core</artifactId>
        <version>4.1.1-SNAPSHOT</version>
    </dependency>

    <dependency>
        <groupId>org.jeasy</groupId>
        <artifactId>easy-rules-mvel</artifactId>
        <version>4.1.1-SNAPSHOT</version>
    </dependency>
</dependencies>

weather-rule.yml

name: "weather rule"
description: "if it rains then take an umbrella"
condition: "rain == true"
actions:
  - "System.out.println(\"It rains, take an umbrella!\");"
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)
}

构想的一个应用场景:

代码

根据测点属性或数据,来判断需要执行哪些操作:

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时执行指定过滤和分析操作。

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

Low-code programming for event-driven applications

概念

Node 节点 、Flow 流程 、Workspace 工作区间、Subflow 子流程、Sidebar 侧边栏、Palette调色板、Wire连接线

安装

#windows
npm install --global --production windows-build-tools

npm install -g --unsafe-perm node-red

http://localhost:1880/

%user%\.node-red\settings.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

Second Flow:

安心云数据处理

安心云的上报流程

image-20210616160110681

总结一般的推送流程:

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 边缘计算

低时延、大带宽、大连接、本地化