3步搞定任务系统改造:规则引擎实战指南,开发效率提升80%!

点击上方“程序员蜗牛g”,选择“设为星标”

跟蜗牛哥一起,每天进步一点点

程序员蜗牛g

大厂程序员一枚 跟蜗牛一起 每天进步一点点

31篇原创内容

公众号

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

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

比如:

  • 打车软件去完成一笔订单可以给用户发一个奖品;

  • 如用户去申请白条的额度,就能给用户发放京豆;

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

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

如:

  • 电商业务: 用户支付一笔3000元以上的订单,完成【订单任务】

  • 商业化业务: 用户完成一个app下载,且打开app浏览10秒,完成【app下载任务】

  • 生活业务: 用户完成一笔话费充值,且充值金额大于50元,完成【话费充值业务】

具体的流程图如下:

图片

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

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

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

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

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

1、统一消息格式

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

但是系统的现状为,各个业务的消息体虽都是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元,用户本次是首次交易】。

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

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

2、完成条件可配置化

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

图片

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

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

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

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

其系统流程图如下(图2.1):

图片

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

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

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

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

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

图片

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

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

结论

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

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

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。

关注公众号:woniuxgg,在公众号中回复:笔记  就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值