SpEL在动态执行业务中的应用

前言

相信做java后端的coder都对SpEL有所了解。

本篇blog不是详细介绍SpEL的定义、功能和详细的使用方法的文章,是想和大家分享一下实际业务中遇到的问题和最终使用SpEL做为解决方案的思考过程。

在笔者所处的物联网行业中平台端需要对设备端上报的数据进行监控和告警。告警规则需要支持后台配置,可动态配置告警指标和告警阈值以及告警短信和邮件的消息模板

这个业务需要中需要动态配置3个数据

  • 告警指标
  • 告警阈值
  • 告警消息模板

1. 告警指标

告警指标由业务决定了其所在领域内的关注点,程序需要能够根据配置取得对应的值

2. 告警阈值

告警阈值决定了告警的触发条件类似于规则引擎中规则命中和工作流引擎中的网关。

会遇到简单的关系运算如 temperature > 40(温度大于40°C触发告警),多条件关系运算 temperature > 25 & humidity > 30 (温度大于25°C并且湿度大于30%触发告警)等业务需求。

3. 告警消息模板

产生了相应的告警事件后需要将告警信息通过短信或者邮件发送出去,根据市场需求平台需要支持客户可以按照自己的行业特性自行定义告警的内容。

基于SpEL强大的运行时执行,解决监控告警需求

解决动态获取告警指标值

SpEL 支持访问属性,数组,集合,可以根据一个特定的对象实例求其内部的属性值

比如需要获取设备上报的电流值

DeviceStatusDTO deviceStatusDto = DeviceStatusDTO.builder()
                .ueSn("P004000000")
                .productCode("6")
                .storeId(20140L)
                .ueType(4)
                .voltage(30.0)
                .electricity(10.0)
                .temperature(40.0)
                .lastReportTime(new Date())
                .build();
                
ExpressionParser parser = new SpelExpressionParser();
Expression expTargetValue = parser.parseExpression("electricity");
// targetValue 即为deviceStatusDto对象中的electricity属性值
Object targetValue = expTargetValue.getValue(deviceStatusDto);

解决告警阈值即告警规则的命中问题

SpEL 支持关系运算

DeviceStatusDTO deviceStatusDto = DeviceStatusDTO.builder()
                .ueSn("P004000000")
                .productCode("6")
                .storeId(20140L)
                .ueType(4)
                .voltage(30.0)
                .electricity(10.0)
                .temperature(40.0)
                .lastReportTime(new Date())
                .build();
                
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("temperature > 55");
boolean fire = exp.getValue(deviceStatusDto, Boolean.class);
if(fire) {
    // 触发告警逻辑
    ...
}

告警消息模板

SpEL 支持对象调用等对象操作

DeviceStatusDTO deviceStatusDto = DeviceStatusDTO.builder()
                .ueSn("P004000000")
                .productCode("6")
                .storeId(20140L)
                .ueType(4)
                .voltage(30.0)
                .electricity(10.0)
                .temperature(40.0)
                .lastReportTime(new Date())
                .build();
                
// 根据SpringEL告警模板生成告警内容
ExpressionParser parser = new SpelExpressionParser();
Expression expAlarmDesc = parser.parseExpression("'温度告警SN:' + ueSn + '温度:' + temperature + '℃'");
String alarmDesc = expAlarmDesc.getValue(deviceStatusDto, String.class);

使用告警配置表存储SpEL表达式满足市场可自由配置化需求

CREATE TABLE `e_ue_alarm_config` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `version` int(10) NOT NULL COMMENT '版本',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `modify_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  `product_code` varchar(32) NOT NULL COMMENT '产品编码',
  `alarm_target` varchar(255) NOT NULL COMMENT '告警指标(SprEL表达式)',
  `alarm_condition` varchar(255) NOT NULL COMMENT '告警条件(SprEL表达式)',
  `alarm_channel` varchar(255) NOT NULL COMMENT '告警通道 邮件:E_MAIL、App推送: PUSH、短信: SMS ,多个使用,号分割',
  `alarm_receiver` varchar(255) NOT NULL COMMENT '告警接收人',
  `alarm_template` varchar(500) NOT NULL COMMENT '告警内容模板(SprEL表达式',
  `alarm_frequency` int(10) NOT NULL COMMENT '告警频率(告警间隔时间 单位:分钟)',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;
告警规则配置示例
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,376评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,126评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,966评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,432评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,519评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,792评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,933评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,701评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,143评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,488评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,626评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,292评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,896评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,742评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,324评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,494评论 2 348

推荐阅读更多精彩内容