专栏名称: 芋道源码
纯 Java 源码分享公众号,目前有「Dubbo」「SpringCloud」「Java 并发」「RocketMQ」「Sharding-JDBC」「MyCAT」「Elastic-Job」「SkyWalking」「Spring」等等
目录
相关文章推荐
芋道源码  ·  万字长文解析OpenAI o1 ... ·  2 天前  
芋道源码  ·  如何设计一个全局唯一的订单号? ·  4 天前  
Java编程精选  ·  SpringCloud+Gateway+Se ... ·  6 天前  
芋道源码  ·  SpringBoot3实战:实现接口签名验证 ·  6 天前  
51好读  ›  专栏  ›  芋道源码

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

芋道源码  · 公众号  · Java  · 2024-11-07 09:30

正文

👉 这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入芋道快速开发平台知识星球。下面是星球提供的部分资料: 

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号、CRM 等等功能:

  • Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本 

来源:juejin.cn/post/
7401403660246614070


前言

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

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

比如:

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

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

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

如:

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

具体的流程图如下:

任务系统重构

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

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

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

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

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

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

统一消息格式

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

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

统一消息格式的好处

因此我先要求业务方的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元,用户本次是首次交易】。

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

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

完成条件可配置化

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

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

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

根据我从业经验,这种规则支持配置的场景,便是【规则引擎】的最佳使用场景。结合项目组的现状,我决定使用阿里的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, nulltruefalse);

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

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

其系统流程图如下:

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

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

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

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

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

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

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

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

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

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

结论

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

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


欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,长按”或“扫描”下方二维码噢

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

文章有帮助的话,在看,转发吧。

谢谢支持哟 (*^__^*)