Node-Red在报警管理中的应用研究
需求说明
报警数据源需求:
- 外部系统接口数据
- Sql查询数据
- 数据库变动数据(CDC)
报警规则定义需求:
- 阈值定义
规则触发需求:
- 任务周期调度
- 实时规则计算
消息发送需求:
- 发送邮件
- 内容系统消息
- 声音
- 发起调令或问题督办
研究任务分解
本次主要研究数据源为接口的方式
- 界面设计
- 数据库设计
/*
Navicat Premium Data Transfer
Source Server : bmc
Source Server Type : Oracle
Source Server Version : 110200
Source Host : 191.168.6.115:1521
Source Schema : BMC
Target Server Type : Oracle
Target Server Version : 110200
File Encoding : 65001
Date: 01/09/2021 16:32:40
*/
-- ----------------------------
-- Table structure for BMC_ALARM_CONFIG
-- ----------------------------
DROP TABLE "BMC"."BMC_ALARM_CONFIG";
CREATE TABLE "BMC"."BMC_ALARM_CONFIG" (
"rulecode" VARCHAR2(100 BYTE) NOT NULL ,
"flowName" VARCHAR2(100 BYTE) ,
"ruleProp" VARCHAR2(100 BYTE)
)
TABLESPACE "SYSTEM"
LOGGING
NOCOMPRESS
PCTFREE 10
INITRANS 1
STORAGE (
INITIAL 65536
NEXT 1048576
MINEXTENTS 1
MAXEXTENTS 2147483645
FREELISTS 1
FREELIST GROUPS 1
BUFFER_POOL DEFAULT
)
PARALLEL 1
NOCACHE
DISABLE ROW MOVEMENT
;
COMMENT ON COLUMN "BMC"."BMC_ALARM_CONFIG"."rulecode" IS '规则编码';
COMMENT ON COLUMN "BMC"."BMC_ALARM_CONFIG"."flowName" IS '流程名称';
COMMENT ON COLUMN "BMC"."BMC_ALARM_CONFIG"."ruleProp" IS '规则属性';
-- ----------------------------
-- Primary Key structure for table BMC_ALARM_CONFIG
-- ----------------------------
ALTER TABLE "BMC"."BMC_ALARM_CONFIG" ADD CONSTRAINT "SYS_C009377" PRIMARY KEY ("rulecode");
COMMIT;
- 环境搭建
主要环境包括:amis、node-red、oracle,为了简化配置解决应用间的跨域访问,需要如下操作:
- 测试环境下chrome 跨域问题解决
- 创建Chrome.command
#!/bin/sh
open -n -a '/Applications/Google Chrome.app' --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
- 添加执行权限
chmod +x Chrome.command
- node-red与应用集成
- 配置根据流程名称获取ID流程
对应的node-red配置如下:
[
{
"id": "17dc371bf93869af",
"type": "tab",
"label": "根据名称获取流程ID",
"disabled": false,
"info": ""
},
{
"id": "c8107088.37ef9",
"type": "http in",
"z": "17dc371bf93869af",
"name": "",
"url": "/getIdByName",
"method": "get",
"upload": false,
"swaggerDoc": "",
"x": 190,
"y": 100,
"wires": [
[
"ede5c092c7422041"
]
]
},
{
"id": "4e8237da.b17dc8",
"type": "template",
"z": "17dc371bf93869af",
"name": "page",
"field": "payload",
"fieldType": "msg",
"format": "handlebars",
"syntax": "mustache",
"template": "{{payload.id}}",
"x": 390,
"y": 420,
"wires": [
[
"65401623.9abfe8"
]
]
},
{
"id": "65401623.9abfe8",
"type": "change",
"z": "17dc371bf93869af",
"name": "Set Headers",
"rules": [
{
"t": "set",
"p": "headers",
"pt": "msg",
"to": "{}",
"tot": "json"
},
{
"t": "set",
"p": "headers.content-type",
"pt": "msg",
"to": "application/json",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 410,
"y": 500,
"wires": [
[
"f7d3e35a.082c2"
]
]
},
{
"id": "f7d3e35a.082c2",
"type": "http response",
"z": "17dc371bf93869af",
"name": "",
"x": 390,
"y": 580,
"wires": []
},
{
"id": "af4410e110cdd7da",
"type": "file in",
"z": "17dc371bf93869af",
"name": "",
"filename": "/root/.node-red/projects/bmc/flow.json",
"format": "utf8",
"chunk": false,
"sendError": false,
"encoding": "utf8",
"allProps": false,
"x": 430,
"y": 180,
"wires": [
[
"d3216179cccc2c59"
]
]
},
{
"id": "d3216179cccc2c59",
"type": "json",
"z": "17dc371bf93869af",
"name": "",
"property": "payload",
"action": "",
"pretty": false,
"x": 390,
"y": 280,
"wires": [
[
"79b68ccb5dd8593f"
]
]
},
{
"id": "79b68ccb5dd8593f",
"type": "function",
"z": "17dc371bf93869af",
"name": "",
"func": "let j = msg.payload;\nlet name = msg.topic;\nlet s = JSONPath({json:j, path: \"$..[?(@.label=='\"+name+\"')]\"});\nmsg.payload = s[0];\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [
{
"var": "JSONPath",
"module": "JSONPath"
}
],
"x": 390,
"y": 360,
"wires": [
[
"4e8237da.b17dc8"
]
]
},
{
"id": "ede5c092c7422041",
"type": "change",
"z": "17dc371bf93869af",
"name": "",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "payload.name",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 400,
"y": 100,
"wires": [
[
"af4410e110cdd7da"
]
]
},
{
"id": "04f519f5d2644962",
"type": "comment",
"z": "17dc371bf93869af",
"name": "读取node-red配置文件",
"info": "",
"x": 640,
"y": 140,
"wires": []
},
{
"id": "7de1b109840d5c92",
"type": "comment",
"z": "17dc371bf93869af",
"name": "对Json对象进行名称搜索",
"info": "",
"x": 590,
"y": 360,
"wires": []
},
{
"id": "3ec69bb3f63f34af",
"type": "comment",
"z": "17dc371bf93869af",
"name": "获取接口查询参数",
"info": "",
"x": 520,
"y": 60,
"wires": []
},
{
"id": "5974541d4456a07b",
"type": "comment",
"z": "17dc371bf93869af",
"name": "json对象转换",
"info": "",
"x": 560,
"y": 280,
"wires": []
}
]
- 调用上述接口获取id,并作为参数传入iframe src中
完整前端配置代码如下:
{
"type": "page",
"body": [
{
"type": "input-text",
"label": "事件编号",
"name": "ruleCode"
},
{
"type": "input-text",
"label": "事件测试属性",
"name": "textProp"
},
{
"type": "form",
"title": "",
"body": [
{
"type": "input-text",
"label": "规则配置地址",
"name": "configUrl",
"value": "7"
},
{
"type": "switch",
"option": "",
"name": "config",
"optionAtLeft": false,
"trueValue": 1,
"falseValue": 0,
"onText": "配置规则",
"offText": "查看规则"
},
{
"type": "service",
"body": [
{
"type": "tpl",
"tpl": "内容",
"inline": false
},
{
"type": "iframe",
"src": "http://191.168.6.115:1880/#flow/${flowId}",
"height": 500
}
],
"api": {
"method": "get",
"url": "http://191.168.6.115:1880/getIdByName?name=${configUrl}",
"responseData": null,
"adaptor": "debugger;\nvar id = payload;\napi.data = {flowId:id}\nreturn api;"
},
"messages": {
},
"visibleOn": "this.config===1"
}
],
"debug": false
}
],
"data": {
"iframeSrc": "http://191.168.6.115:1880/#flow/7f6af7842123485a"
}
}
- node-red模拟数据接口
[
{
"id": "7f37b6574efaba2a",
"type": "tab",
"label": "外部系统模拟接口",
"disabled": false,
"info": ""
},
{
"id": "c860701999955a6a",
"type": "http in",
"z": "7f37b6574efaba2a",
"name": "",
"url": "/mockAlermData",
"method": "get",
"upload": false,
"swaggerDoc": "",
"x": 240,
"y": 200,
"wires": [
[
"2a38222dfc31155e"
]
]
},
{
"id": "2a38222dfc31155e",
"type": "template",
"z": "7f37b6574efaba2a",
"name": "",
"field": "payload",
"fieldType": "msg",
"format": "handlebars",
"syntax": "mustache",
"template": "{\n \"system\":\"Mes\",\n \"alermContent\":\"本月配套计划延迟\",\n \"delayDays\":\"0\",\n \"sendTime\":\"2021-09-01\"\n}",
"output": "json",
"x": 480,
"y": 220,
"wires": [
[
"6809fb4a334ff5dd"
]
]
},
{
"id": "7b4cda9c362c18dc",
"type": "http response",
"z": "7f37b6574efaba2a",
"name": "",
"statusCode": "",
"headers": {},
"x": 710,
"y": 200,
"wires": []
},
{
"id": "6809fb4a334ff5dd",
"type": "function",
"z": "7f37b6574efaba2a",
"name": "",
"func": "msg.payload.sendTime=new Date();\nvar num=Math.floor(Math.random()*10+1);\nmsg.payload.delayDays = num;\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 600,
"y": 320,
"wires": [
[
"7b4cda9c362c18dc"
]
]
}
]
- node-red调用接口并进行规则设置计算
- 调用node-red新建流程
{
"type": "submit",
"label": "创建告警规则",
"actionType": "ajax",
"api": {
"method": "post",
"url": "http://191.168.6.115:1880/flow",
"dataType": "json",
"data": null,
"requestAdaptor": "debugger;\nvar nodeRedData = {\n \"label\":this.data.configUrl,\n \"nodes\":[],\n \"configs\":[]\n}\napi.data=nodeRedData;\nreturn api;"
}
}
- 使用kafka接受接口推送数据
- 使用kafka实时消费产生告警
- 发起调令