欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

drools规则引擎实现动态配置规则

程序员文章站 2022-05-28 11:38:59
...

       先说下我的业务需求背景,最近公司要推出运营活动,根据用户行为送用户积分;比如用户注册送、首次消费送,非首次消费送、累积消费送、针对我们这个的特殊要求是跟具体规则绑定;比如说

规则1 用户累积消费首次达到10000送积分20;

规则2 用户累积投资首次达到 20000 送积分40;

这两条规则是不能同时生效,但如果他们的时间是错开用户是可以针对这两条规则获取到奖励的

用户然后运营想做到的效果是服务端一次性做好,运营配置规则不用服务端再修改代码;这是运营需求.

经过调研决定用drools规则引擎来做,首先添加maven依赖:

<dependency>
    <groupId>org.kie</groupId>
    <artifactId>kie-api</artifactId>
    <version>${drools.version}</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-core</artifactId>
    <version>${drools.version}</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-compiler</artifactId>
    <version>${drools.version}</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-decisiontables</artifactId>
    <version>${drools.version}</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-templates</artifactId>
    <version>${drools.version}</version>
</dependency>

然后提供规则引擎的执行方法:

public T execute(List<Rule> 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

有问题可加qq 2393399306,欢迎一起探讨