记一次使用规则引擎改造任务系统的经验

科技   2024-11-08 15:08   安徽  

来源:juejin.cn/post/7401403660246614070

👉 欢迎加入小哈的星球,你将获得: 专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 点击查看项目介绍
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2期已完结,演示链接:http://116.62.199.48/;

截止目前,累计输出 65w+ 字,讲解图 2776+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,解锁全部项目,已有2300+小伙伴加入

  • 前言
  • 痛点解决-如何避免对接新的任务,改造代码
  • 结论

前言

笔者在去年接手了公司的活动中台,其中【任务】,是活动当中必不可缺的玩法之一。

相信大家都在各种各样的互联网活动中体验过【任务】。

比如:

  • 打车软件去完成一笔订单可以给用户发一个奖品;
  • 如用户去申请白条的额度,就能给用户发放京豆;

从技术思维上,以上的流程,可以抽象成,用户完成某个动作,就给用户发放对应的奖品

作为中台的任务系统,往往会对接上游N个业务方的不同任务,并且任务也会有不同的完成条件。

如:

电商业务:用户支付一笔3000元以上的订单,完成【订单任务】 商业化业务:用户完成一个app下载,且打开app浏览10秒,完成【app下载任务】 生活业务:用户完成一笔话费充值,且充值金额大于50元,完成【话费充值业务】

具体的流程图如下:

img

任务系统重构

可以看到,业务侧将消息通过RocketMQ的方式,通知至任务系统。

痛点解决-如何避免对接新的任务,改造代码

以上方式,会有一个实实在在的痛点:每次任务完成条件发生变更,就需要任务系统更改代码,现状需要一周的时间去对接一个新的任务。

举个例子,假如电商业务中,【订单任务】的完成条件从【3000元以上订单】调整为【5000元以上订单】,任务系统每次还得去调整代码,以支持【5000元以上订单】完成的条件。这种如此慢的迭代方式,显然是不够支持业务的发展速度。

所以任务系统的行动点就是:任务完成条件变动,做成可配置化,支持运营在后台管理系统随时调整任务的配置条件。

统一消息格式

其实仔细分析,任务完全可以抽象成为:针对某个行为, 判断行为中的条件是否满足运营配置的要求

但是系统的现状为,各个业务的消息体虽都是json格式,但格式都不一致,任务系统写了很多针对不同消息格式的定制化代码适配,其流程图如下:

img

统一消息格式的好处

因此我先要求业务方的mq格式消息体进行改造,按照任务系统的统一标准进行格式传递。

标准消息体格式如下
"userid""",  
"business""",
"behavior""" ,     
"behaviorTime""",
"extraData": {  
}

userId是用户的id,business是该事件所属业务,behaviorTime是行为发生的时间, behavior就是用户具体的任务行为,比如【完成订单叫pay_order_success】, app下载叫【app_download】, 话费充值叫【tel_recharge】。

最为关键的是extraData, 这个字段是拓展字段,主要用于存放每个行为的附加条件,比如:

【完成订单】,该字段可以存放订单交易金额,是否首次下单,那么完成订单的完整消息为:

"userid""12345"
"business""onlineShop",
"behavior""pay_order_success" ,     
"behaviorTime""完成订单时间戳",
"extraData": {    
    "tradeTotalMoney": 500000, 
    "firstTime"true
}

以上完成消息对应的中文含义为:用户12345, 在某个时间,完成了【电商业务】中的【下单成功】行为,行为的附加属性为:【交易金额大于5000元,用户本次是首次交易】。

之后,所有对接任务系统的任务,业务方必须按照我的要求,来传递消息。

做好了任务消息的标准化,就开始下一步优化:如何将完成条件进行抽象,做成可配置化管理?

完成条件可配置化

想把任务完成的配置完全交给运营,首先需要有个类似下面这种配置的管理后台,为简单的画一下管理后台的原型。

img

任务系统重构-后台管理示意图

灵魂画家。。。总而言之,就是把任务的完成条件开放至运营,并支持可配。

根据我从业经验,这种规则支持配置的场景,便是【规则引擎】的最佳使用场景。结合项目组的现状,我决定使用阿里的QLExpress, 并进行重构。

QLEpress介绍如下:

https://github.com/alibaba/QLExpress  
由阿里的电商业务规则、表达式(布尔组合)、特殊数学公式计算(高精度)、语法分析、脚本二次定制等强需求而设计的一门动态脚本引擎解析工具。  
在阿里集团有很强的影响力,同时为了自身不断优化、发扬开源贡献精神,于2012年开源

引入了规则引擎后,在判断任务完成的代码时候,其实就是对QlExpress的脚本进行判断,任务的完成条件可以表现为一串脚本命令,如:

tradeTotalMoney >= 300000 && firstTime = true 

在执行完成任务代码的时候,任务系统会将【任务消息体】中的extraData,构造成一个HashMap, 传入到QLEpress的api中。

"userid""12345"
"business""onlineShop",
"behavior""pay_order_success" ,     
"behaviorTime""完成订单时间戳",
"extraData": {    
    "tradeTotalMoney": 500000, 
    "firstTime"true
}

使用QLEpress的api,express就是【脚本命令】, context是一个Map,对于任务系统来说,就会把extraData传入函数中。

Object r = runner.execute(express, context, null, truefalse);

对于QLEpress来说也很简单,就是做了Map对象中的key替换的动作,实际上就是执行以下的这段代码:

Object r = 500000  >= 300000 && true = true 

其系统流程图如下:

img

任务系统重构-系统交互流程

假如运营现在想把任务系统中【完成订单】的完成条件中的订单交易金额5000改成3000,也很简单了,只需通过后台管理系统更改配置就能实现任务的调整。

后台系统新增条件的可配置化。

你以为以上就是最终方案了么,对接新的任务就不用开发了么?

其实不然,细心的读者会发现,后台系统如果要新增 【任务完成行为】 和【完成条件】,后台管理系统还是得开发代码。比如:需要新增一个【加入购物车】的任务,还是需要后台系统开发。

所以,我们的下一步优化策略,是将【任务完成行为】和 【完成条件】做成配置化,后台动态读取数据库的配置进行显示,其流程如下:

img

任务系统重构-支持元数据配置

这里我把属于【规则引擎】的内容抽象成一个系统,让这个系统去对规则领域的内容进行管理。

其实12步,“引入【规则引擎系统提供的sdk】,执行规则引擎代码 ”,有两种方案,也可以由任务系统在交互的过程中,传入参数,去调用【规则引擎系统】提供的RPC接口,但考虑到增加了一层网络开销,且规则引擎执行的场景也相对简单,不会对规则引擎的代码进行过多调整,所以采取的是引入sdk的方式,通过本地代码执行去减少不必要的网络开销。

结论

经过规则引擎的重构后,再对接新的任务,只需通过开发1分钟在后台配置元数据,即可完成新的任务对接,比起之前动辄一周的新任务对接,大大提高了效率。

笔者也通过这次改造获得了公司的好绩效,并将这种规则引擎的能力,提供给其它系统使用,真正实现了开发驱动业务。

👉 欢迎加入小哈的星球,你将获得: 专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 点击查看项目介绍
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2期已完结,演示链接:http://116.62.199.48/;

截止目前,累计输出 65w+ 字,讲解图 2776+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,解锁全部项目,已有2300+小伙伴加入


1. 我的私密学习小圈子,从0到1手撸企业实战项目!

2. SpringBoot + minio + kkfile 实现文件预览

3. 四选一,如何选择适合你的分页方案?

4. SpringBoot 打造图片阅后即焚功能

最近面试BAT,整理一份面试资料Java面试BATJ通关手册,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。

获取方式:点“在看”,关注公众号并回复 Java 领取,更多内容陆续奉上。

PS:因公众号平台更改了推送规则,如果不想错过内容,记得读完点一下在看,加个星标,这样每次新文章推送才会第一时间出现在你的订阅列表里。

“在看”支持小哈呀,谢谢啦

小哈学Java
码龄9年,前某厂中台研发。专注于Java领域干货分享,不限于BAT面试, 算法,数据库,Spring Boot, 微服务,高并发, JVM, Docker容器,ELK相关知识,期待与您一同进步。
 最新文章