规则引擎EasyRules详解

规则引擎EasyRules

背景

业务系统在应用过程中,常常包含着要处理"复杂、多变"的部分,这部分往往是"业务规则"或者是"数据的处理逻辑"。因此这部分的动态规则的问题,往往需要可配置,并对系统性能和热部署有一定的要求。

什么是规则引擎?

规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。

规则引擎的核心概念

Rule:规则整体

Fact:输入对象

condition:执行条件

Action:执行动作

Output:结果对象

priority:执行优先级

业务场景

在电商评价系统中,需要对每个用户的评价做风控处理,很多风控规则需要适时调整的,针对于不同的场景使用不同的风控策略来对评价进行过滤是至关重要的。EasyRules作为一个基于java轻量级的规则引擎,学习成本更低、适用性更强,故而选择使用EasyRules实践规则引擎。


实现

    /**
     * 下面的案例 简单的说就是将一堆的if eles 简化了 使用
     *  easy rules 引擎计算了一切,方便很多
     * @param args
     */
    public static void main(String[] args) {
        //创建一个评价实例(Fact),注:commentMap存放了评价列表数据
        Facts facts = new Facts();
        facts.put("commentMap", commentMap);

        //链式编程
        Rule rule1 = new RuleBuilder()
                .name("rule1")
                .description("最近7天内,单笔订单超过3个 (含3个) 以上商品1-2星差评;")
                .priority(1)
                .when(f -> {
                    boolean flag=false;
                    CommentMap.forEach((orderId, commentItems) -> {
			              long negativeCount = commentItems.stream().filter(o -> Arrays.asList(1, 2).contains(o.getStartNum())).count();
              						if (negativeCount >= 3) {
                    				flag=true;
                    			}
		                });
		                return flag;
                })
                .then(f -> {
                    // 说明被风控了
    					      o.setStatus(AfterSaleCommentRiskStatusEnum.RISK.getValueDefined());
                })
                .build();
        //表达式 -- 常用的 不支持正则匹配
                Rule rule2 = new MVELRule()
                .name("rule2")
                .description("最近7天内,单笔订单超过3个 (含3个) 以上商品1-2星差评;")
                .priority(1)
                .when(
                    "CommentMap.values().stream().anyMatch(commentItems -> " +
                    "   commentItems.stream().filter(o -> [1, 2].contains(o.startNum)).count() >= 3" +
                    ")"
                )
                .then(
                    "o.setStatus(AfterSaleCommentRiskStatusEnum.RISK.getValueDefined())"
                )
                .build();

        //还可以支持yaml的形式
        //。。。。。。yaml 和上面的支持格式是一样的,写的地方不一致而已,项目中使用表达式的方式居多

        Rules rules = new Rules();
        rules.register(rule1);
//        rules.register(rule2);
          RulesEngineParameters parameters = new RulesEngineParameters()
              .rulePriorityThreshold(10)//当优先级超过10时,跳过余下的规则。
              .skipOnFirstAppliedRule(true)//当一个规则成功应用时,跳过余下的规则。
              .skipOnFirstFailedRule(true)//当一个规则失败时,跳过余下的规则。
              .skipOnFirstNonTriggeredRule(true);//当一个规则未触发时,跳过余下的规则。
        //创建规则执行引擎,并执行规则
        RulesEngine rulesEngine = new DefaultRulesEngine(parameters);
        rulesEngine.fire(rules, facts);
        System.out.println(tom);
    }

基于JSON格式定义Rule

[{
  "name": "1",
  "description": "1",
  "priority": 1,
  "compositeRuleType": "UnitRuleGroup",
  "composingRules": [
    {
      "name": "2",
      "description": "2",
      "condition": "user.getAge()<28",
      "priority": 2,
      "actions": [
        "System.out.println(\"UnitRuleGroup not ok rule2 \")"
      ]
    },
    {
      "name": "3",
      "description": "3",
      "condition": "user.name.length<10",
      "priority": 3,
      "actions": [
        "System.out.println(\"UnitRuleGroup rule3 \")"
      ]
    },
    {
      "name": "4",
      "description": "4",
      "condition": "user.name.length<10",
      "priority": 4,
      "actions": [
        "System.out.println(\"UnitRuleGroup rule4 \")"
      ]
    },
    {
      "name": "5",
      "description": "5",
      "condition": "user.name.length<10",
      "priority": 5,
      "actions": [
        "System.out.println(\"UnitRuleGroup rule5 \");UserService.doAction4(user.userinfo)"
      ]
    }
  ]},
  {
    "name": "3",
    "description": "3",
    "condition": "user.name.length<50",
    "priority": 3,
    "actions": [
      "System.out.println(\"default rule3 \")"
    ]
  }
]
  Facts facts = new Facts();
  facts.put("commentMap", commentMap);
	MVELRuleFactory ruleFactory = new MVELRuleFactory(new JsonRuleDefinitionReader());
	Rules rules = ruleFactory.createRules(new FileReader(Launcher.class.getClassLoader().getResource("json-rule.json").getFile()),context);
	DefaultRulesEngine rulesEngine = new DefaultRulesEngine();
	rulesEngine.fire(rules, facts);
posted @ 2025-05-19 11:19  异人程序员  阅读(841)  评论(0)    收藏  举报