关于Drools规则引擎的应用和一些思考

一、背景

    博主是一家国内大型保险公司的苦逼开发,日常工作中,需要接触大量的客户风控相关的规则,面临大量的差异化逻辑,如机构差异,业务员差异,客户个体差异,甚至不同的销售平台差异也相当大,其中的逻辑复杂程度只会比我们想象的更复杂,更难受的,这些业务规则经常会发生变更发生更改。为了适应这样的需求,我们的 IT 业务系统应该能快速且低成本的更新。适应这样的需求,一般的作法是将业务规则的配置单独拿出来,使之与业务系统保持低耦合。目前,实现这样的功能的程序,已经被开发成为规则引擎。

二、方案应对

    规则引擎是一种推理引擎,它是根据已有的事实,从规则知识库中匹配规则,并处理存在冲突的规则,执行最后筛选通过的规则。因此,规则引擎是人工智能(AI)研究领域的一部分,具有一定的选择判断性、人工智能性和富含知识性。目前,比较流行的规则引擎有商业规则引擎 iLog 和开源规则引擎 drools。本文将对开源规则引擎 drools 做详细介绍,并通过分析一个在保险行业中的实际应用案例,让各位对开源规则流引擎有一个更深刻的理解。

  针对这些情况,我们提供成熟的处理业务规则的方案,如下: 

1.将业务逻辑与业务规则分离,业务规则集中管理。 简化系统架构,方便后期维护。 

2.编写规则文件来实现业务规则,并通过架包存放所有规则文件。 规则文件逻辑结构清晰好理解,写规则文件如写SQL脚本一样,语法简单易学。 每个规则逻辑独立,耦合度降低,可以快速准确定位问题。 规则包可以通过版本进行控制,修改记录清晰明确。 方便在编辑环境下,对规则进行单元测试。 

3.通过调用规则执行子系统获取业务规则推理结论。 规则推理时采用快速匹配算法,其匹配速度与规则数目无关,非常适用于拥有大批量业务规则的场景。 支持不停机更新规则,快速响应生产事件。 方便对规则包进行整体测试。 

4.通过规则管理子系统对规则进行管理。 方便查看规则包内规则文件。 修改业务规则执行时用到的动态参数,并提供权限控制保证数据安全。 快速查询每次规则执行入参与执行结果,方便排查问题。 

三、代码

举个非常简单的例子,校验某客户的理赔信息,这个客户的理赔标识在业务系统已经提前取到,需要校验时和其他所有的信息一起通过调用drools相关的规则系统进行规则校验:

package com.xxx.lcloud.rules.bean.vo;

import com.xxx.lcloud.frs.api.base.Translate;
import com.xxx.lcloud.rules.bean.vo.addition.InsurantAddition;
import com.xxx.lcloud.rules.bean.vo.base.Insurant;
import java.io.Serializable;

@Translate("被保人对象")
public class InsurantVO implements Serializable {
    private static final long serialVersionUID = 1L;
    private Insurant insurant = new Insurant();
    private InsurantAddition insurantAddition = new InsurantAddition();

    public String toString() {
        return "InsurantVO [insurant=" + this.insurant + ", insurantAddition=" + this.insurantAddition + "]";
    }

    public InsurantVO() {
    }

    public Insurant getInsurant() {
        return this.insurant;
    }

    public void setInsurant(Insurant insurant) {
        this.insurant = insurant;
    }

    public InsurantAddition getInsurantAddition() {
        return this.insurantAddition;
    }

    public void setInsurantAddition(InsurantAddition insurantAddition) {
        this.insurantAddition = insurantAddition;
    }
}
复制代码
package com.xxx.lcloud.rules.bean.vo.addition;xxx
import com.xxx.lcloud.frs.api.base.Translate;
import java.io.Serializable;
import java.math.BigDecimal;

@Translate("被保人附加信息")
public class InsurantAddition implements Serializable {
    private static final long serialVersionUID = 1L;
  
    @Translate("特殊理赔记录标识")
    private Boolean specialClaimFlag;


    public Boolean getSpecialClaimFlag() {
        return this.specialClaimFlag;
    }

    public void setSpecialClaimFlag(Boolean specialClaimFlag) {
        this.specialClaimFlag = specialClaimFlag;
    }

 
}复制代码

规则文件:

package rules

import com.xxx.lcloud.rules.bean.vo.*;
import com.xxx.lcloud.rules.bean.vo.base.*;
import com.xxx.lcloud.rules.bean.vo.addition.*;
import com.xxx.lcloud.rules.bean.results.*
import com.xxx.lcloud.rcs.util.ClientType;
rule "insured"
    dialect "mvel"

when
    InsurantVO(
        insurant != null,
        insurantAddition != null,
        insurant.mainInsurantFlag == true,
        insurantAddition.specialClaimFlag == true,
        $insurant :insurant
    )    
    executionResult : ExecutionResult()
then
    RuleFailureResult ruleFailureResult = new RuleFailureResult();
    ruleFailureResult.setClientNo($insurant.getClientNo());
    ruleFailureResult.setReasonType("02");
    ruleFailureResult.setReasonDesc("客户存在理赔报案记录");
    ruleFailureResult.setReasonFileCode(drools.getRule().getName());
    executionResult.addRuleFailureResult(ruleFailureResult);
    executionResult.setPassed(false);
end

复制代码

上面代码的语义:如果客户作为主被保人,存在历史理赔记录,需要返回相应的业务规则给到业务系统,统一进行后续的业务流转;

当然,面对更复杂,更奇葩的场景,drools都能帮我们解决问题,比如多条件判断时,我们可以使用决策表,可以把它理解成一张小的数据库表;

   决策表又称判断表,是一种呈表格状的图形工具,适用于描述处理判断条件较多,各条件又相互组合、有多种决策方案的情况。精确而简洁描述复杂逻辑的方式,将多个条件与这些条件满足后要执行动作相对应。但不同于传统程序语言中的控制语句,决策表能将多个独立的条件和多个动作直接的联系清晰的表示出来。

   目的:将相同逻辑不同数据的规则统一整理成决策表

    实现原理:决策表管理决策表头,一个表头可以有多套决策表数据。决策表数据可以与多个业务子规则关联(一般是一个)

    决策表管理用户生成规则包里的xls,决策表就是N条数据生成N条DRL规则,逻辑由表头生成;

   


猜你喜欢

转载自juejin.im/post/5ec222dfe51d454de344de31
今日推荐