先说下我的业务需求背景,最近公司要推出运营活动,根据用户行为送用户积分;比如用户注册送、首次消费送,非首次消费送、累积消费送、针对我们这个的特殊要求是跟具体规则绑定;比如说
规则1 用户累积消费首次达到10000送积分20;
规则2 用户累积投资首次达到 20000 送积分40;
这两条规则是不能同时生效,但如果他们的时间是错开用户是可以针对这两条规则获取到奖励的
用户然后运营想做到的效果是服务端一次性做好,运营配置规则不用服务端再修改代码;这是运营需求.
经过调研决定用drools规则引擎来做,首先添加maven依赖:
org.kie
kie-api
7.7.0.Final
org.drools
drools-core
7.7.0.Final
org.drools
drools-compiler
7.7.0.Final
org.drools
drools-decisiontables
7.7.0.Final
org.drools
drools-templates
7.7.0.Final
然后提供规则引擎的执行方法:
public T execute(List ruleList, T t) {
if (CollectionUtils.isEmpty(ruleList) || t == null) {
return t;
}
logger.info("执行规则引擎 start ....");
System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");
KieHelper helper = new KieHelper();
for (Rule rule : ruleList) {
helper.addContent(rule.getRule(), ResourceType.DRL);
}
KieSession kSession = helper.build().newKieSession();
kSession.insert(t);
kSession.fireAllRules();
kSession.dispose();
logger.info("执行规则引擎 end ....");
return t;
}
推荐使用上面的方法,在添加规则时动态生产drl文件内容并保存到数据库,这样可以不用提前生成drl;在执行的时候直接查数据库,根据不同的类别,比如上面的消费可能有多条规则:比如 规则1消费满1000送10;满2000送20;这样可以一次同一用户行为下的多个规则都加载到规则引擎中,drl文件内容如下:
简单的这个规则对应的运营规则是用户充值200送100积分
package com.wakanda.ruleengine.service.api.event
import com.wakanda.ruleengine.service.api.event.MarketingEvent
rule "1543494757156"
date-effective "2018-08-30 01:58:00"
date-expires "2099-08-30 01:58:00"
activation-group "PASSENGER_BEHAVIOR_SUBJECT_RECHARGE_ALL_ALL_ALL_CHANNEL_SINGLE_AMOUNT_SINGLETON_MONEY"
salience 100.00
when
$s:MarketingEvent(scene == "PASSENGER_BEHAVIOR_SUBJECT_RECHARGE_ALL_ALL_ALL_CHANNEL_SINGLE_AMOUNT" , userType == 1 , useType == 1 , amount >= 200.0)
then
$s.setMarketingRuleId(136L);
$s.setActionType(1);
$s.setActionValue(100.0);
update($s);
end
复杂的:
package com.wakanda.ruleengine.service.api.event
import com.wakanda.ruleengine.service.api.event.MarketingEvent
rule "1542713687828"
date-effective "11-Aug-2017"
date-expires "13-Nov-2019"
activation-group "BEHAVIOR_SUBJECT_RECHARGE_ALL_ALL_CUMULATIVE_NUMBER_TOTAL_TIMES"
salience 600.00
when
$s:MarketingEvent(scene == "BEHAVIOR_SUBJECT_RECHARGE_ALL_ALL_CUMULATIVE_NUMBER" , useType == 1)
not MarketingEvent.UserBehavior(marketingRuleId == 77,userBehaviorUnit == 3, (3 > beforAmount), ($s.amount + beforAmount > 3 || $s.amount + beforAmount == 3)) from $s.userBehaviorList do[FIRST]
or MarketingEvent.UserBehavior(marketingRuleId == 77,userBehaviorUnit == 3, (3 > beforAmount), ($s.amount + beforAmount > 3 || $s.amount + beforAmount == 3)) from $s.userBehaviorList
then
$s.setMarketingRuleId(77L);
$s.setActionType(1);
$s.setActionValue(600.0);
update($s);
then[FIRST]
$s.setMarketingRuleId(77L);
$s.setActionType(1);
$s.setActionValue(0.0);
update($s);
end