规则引擎 | 青训营笔记

138 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 17 天

规则引擎消息

规则引擎消息可以被被序列化并有着规定的数据结构同时可以表示系统中的各种消息。

例如:

  • 设备遥测属性更新RPC调用;

  • 实体生命周期事件: created、updated、deleted、assigned、unassigned、属性更新;

  • 设备状态事件: connected, disconnected, active, inactive, etc;

  • 其他事件。

规则引擎消息包含以下信息:

  • 消息ID:基于时间的通用唯一标识符;

  • 消息发起者:Device,Asset或其他Entity标识符;

  • 消息类型:遥测或不活动的事件等;

  • 消息负载:消息payload的JSON字符串;

  • 元数据:键值对的列表以及与消息有关的其他数据.

规则节点

规则节点是规则引擎的基本组件每次处理单个输入消息并生成一个或多个输出消息。

规则节点是规则引擎的主要逻辑单元。

规则节点可以是Filter、Enrichment、Transform输入消息或者是执行Action与External节点对外部系统进行通信

规则节点关系

规则节点之间存在关联性每个节点都有对应关系类型,用于标识关系的逻辑标签。

当规则节点生成输出消息时,它总是将消息路由到下一个指定的节点并通过关系类型进行关联。

表示成功与否的规则节点关系是SuccessFailure

表示逻辑运算的规则节点可以是TrueFalse

一些特定的规则节点可能使用完全不同的关系类型例如:“Post Telemetry”、“Attributes Updated”、“Entity Created”等。

demo

func TestGoValueate() {   // 支持多个逻辑表达式   expr, err := govaluate.NewEvaluableExpression("(10 > 0) && (2.1 == 2.1) && 'service is ok' == 'service is ok'" +      " && 1 in (1,2) && 'code1' in ('code3','code2',1)")   if err != nil {      log.Fatal("syntax error:", err)   }   result, err := expr.Evaluate(nil)   if err != nil {      log.Fatal("evaluate error:", err)   }   fmt.Println(result)    // 逻辑表达式包含变量   expression, err := govaluate.NewEvaluableExpression("http_response_body == 'service is ok'")   parameters := make(map[string]interface{}, 8)   parameters["http_response_body"] = "service is ok"   res, _ := expression.Evaluate(parameters)   fmt.Println(res)    // 算数表达式包含变量   expression1, _ := govaluate.NewEvaluableExpression("requests_made * requests_succeeded / 100")   parameters1 := make(map[string]interface{}, 8)   parameters1["requests_made"] = 100   parameters1["requests_succeeded"] = 80   result1, _ := expression1.Evaluate(parameters1)   fmt.Println(result1) }

基准测试

func BenchmarkNewEvaluableExpression(b *testing.B) {   for i := 0; i < b.N; i++ {      _, err := govaluate.NewEvaluableExpression("(10 > 0) && (100 > 20) && 'code1' in ('code3','code2',1)")      if err != nil {         log.Fatal("syntax error:", err)      }   }} func BenchmarkEvaluate(b *testing.B) {   parameters1 := make(map[string]interface{}, 8)   parameters1["gmv"] = 100   parameters1["customerId"] = "80"   parameters1["stayLength"] = 20   for i := 0; i < b.N; i++ {      _, err := govaluate.NewEvaluableExpression("(gmv > 0) && (stayLength > 20) && customerId in ('80','code2','code3')")      if err != nil {         log.Fatal("syntax error:", err)      }   }}