注册

这5种规则引擎,真香!

前言


核心痛点:业务规则高频变更与系统稳定性之间的矛盾


想象一个电商促销场景:


// 传统硬编码方式(噩梦开始...)
public BigDecimal calculateDiscount(Order order) {
BigDecimal discount = BigDecimal.ZERO;

if (order.getTotalAmount().compareTo(new BigDecimal("100")) >= 0) {
discount = discount.add(new BigDecimal("10"));
}

if (order.getUser().isVip()) {
discount = discount.add(new BigDecimal("5"));
}

// 更多if-else嵌套...
return discount;
}

当规则变成:"非VIP用户满200减30,VIP用户满150减40,且周二全场额外95折"时,代码将陷入维护地狱!


规则引擎通过分离规则逻辑解决这个问题:



  1. 规则外置存储(数据库/文件)
  2. 支持动态加载
  3. 声明式规则语法
  4. 独立执行环境

下面给大家分享5种常用的规则引擎,希望对你会有所帮助。


最近准备面试的小伙伴,可以看一下这个宝藏网站(Java突击队):www.susan.net.cn,里面:面试八股文、场景题、面试真题、项目实战、工作内推什么都有


1.五大常用规则引擎


1.1 Drools:企业级规则引擎扛把子


官网http://www.drools.org/


适用场景:



  • 金融风控规则(上百条复杂规则)
  • 保险理赔计算
  • 电商促销体系

实战:折扣规则配置


// 规则文件 discount.drl
rule "VIP用户满100减20"
when
$user: User(level == "VIP")
$order: Order(amount > 100)
then
$order.addDiscount(20);
end

Java调用代码:


KieServices kieServices = KieServices.Factory.get();
KieContainer kContainer = kieServices.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("discountSession");

kSession.insert(user);
kSession.insert(order);
kSession.fireAllRules();

优点



  • 完整的RETE算法实现
  • 支持复杂的规则网络
  • 完善的监控管理控制台

缺点



  • 学习曲线陡峭
  • 内存消耗较大
  • 需要依赖Kie容器


适合:不差钱的大厂,规则复杂度高的场景



1.2 Easy Rules:轻量级规则引擎之王


官网github.com/j-easy/easy…


适用场景:



  • 参数校验
  • 简单风控规则
  • 审批流引擎

注解式开发:


@Rule(name = "雨天打折规则", description = "下雨天全场9折")
public class RainDiscountRule {

@Condition
public boolean when(@Fact("weather") String weather) {
return "rainy".equals(weather);
}

@Action
public void then(@Fact("order") Order order) {
order.setDiscount(0.9);
}
}

引擎执行:


RulesEngineParameters params = new RulesEngineParameters()
.skipOnFirstAppliedRule(true); // 匹配即停止

RulesEngine engine = new DefaultRulesEngine(params);
engine.fire(rules, facts);

优点



  • 五分钟上手
  • 零第三方依赖
  • 支持规则组合

缺点



  • 不支持复杂规则链
  • 缺少可视化界面


适合:中小项目快速落地,开发人员不足时



1.3 QLExpress:阿里系脚本引擎之光


官网github.com/alibaba/QLE…


适用场景:



  • 动态配置计算逻辑
  • 财务公式计算
  • 营销规则灵活变更

执行动态脚本:


ExpressRunner runner = new ExpressRunner();
DefaultContext<String, Object> context = new DefaultContext<>();
context.put("user", user);
context.put("order", order);

String express = "if (user.level == 'VIP') { order.discount = 0.85; }";
runner.execute(express, context, null, true, false);

高级特性:


// 1. 函数扩展
runner.addFunction("计算税费", new Operator() {
@Override
public Object execute(Object[] list) {
return (Double)list[0] * 0.06;
}
});

// 2. 宏定义
runner.addMacro("是否新用户", "user.regDays < 30");

优点



  • 脚本热更新
  • 语法接近Java
  • 完善的沙箱安全

缺点



  • 调试困难
  • 复杂规则可读性差


适合:需要频繁修改规则的业务(如运营活动)



1.4 Aviator:高性能表达式专家


官网github.com/killme2008/…


适用场景:



  • 实时定价引擎
  • 风控指标计算
  • 大数据字段加工

性能对比(执行10万次):


// Aviator 表达式
Expression exp = AviatorEvaluator.compile("user.age > 18 && order.amount > 100");
exp.execute(map);

// Groovy 脚本
new GroovyShell().evaluate("user.age > 18 && order.amount > 100");

引擎耗时
Aviator220ms
Groovy1850ms

编译优化:


// 开启编译缓存(默认开启)
AviatorEvaluator.getInstance().useLRUExpressionCache(1000);

// 字节码生成模式(JDK8+)
AviatorEvaluator.setOption(Options.ASM, true);

优点



  • 性能碾压同类引擎
  • 支持字节码生成
  • 轻量无依赖

缺点



  • 只支持表达式
  • 不支持流程控制


适合:对性能有极致要求的计算场景



这里有复杂的商城项目实战,使用技术:SpringBoot、Spring Security、MySQL、Mybatis、shardingsphere、Nacos、JWT、ElasticSearch、Redis、RocketMQ、MongoDB、Caffeine、FreeMaker、Redisson、Minio、WebSocket、hanlp、mahout、jsoup、Docker等等,非常值得一看


1.5 LiteFlow:规则编排新物种


官网:liteflow.com/


适用场景:



  • 复杂业务流程
  • 订单状态机
  • 审核工作流

编排示例:


<chain name="orderProcess">
<then value="checkStock,checkCredit"/> <!-- 并行执行 -->
<when value="isVipUser">
<then value="vipDiscount"/>
</when>
<otherwise>
<then value="normalDiscount"/>
</otherwise>
<then value="saveOrder"/>
</chain>

Java调用:


LiteflowResponse response = FlowExecutor.execute2Resp("orderProcess", order, User.class);
if (response.isSuccess()) {
System.out.println("流程执行成功");
} else {
System.out.println("失败原因:" + response.getCause());
}

优点



  • 可视化流程编排
  • 支持异步、并行、条件分支
  • 热更新规则

缺点



  • 新框架文档较少
  • 社区生态待完善


适合:需要灵活编排的复杂业务流



2 五大规则引擎横向评测



性能压测数据(单机1万次执行):


引擎耗时内存占用特点
Drools420ms功能全面
Easy Rules38ms轻量易用
QLExpress65ms阿里系脚本引擎
Aviator28ms极低高性能表达式
LiteFlow120ms流程编排专家

3 如何技术选型?



黄金法则:



  1. 简单场景:EasyRules + Aviator 组合拳
  2. 金融风控:Drools 稳如老狗
  3. 电商运营:QLExpress 灵活应变
  4. 工作流驱动:LiteFlow 未来可期

4 避坑指南



  1. Drools内存溢出

// 设置无状态会话(避免内存积累)
KieSession session = kContainer.newStatelessKieSession();


  1. QLExpress安全漏洞

// 禁用危险方法
runner.addFunctionOfServiceMethod("exit", System.class, "exit", null, null);


  1. 规则冲突检测

// Drools冲突处理策略
KieSessionConfiguration config = KieServices.Factory.get().newKieSessionConfiguration();
config.setProperty("drools.sequential", "true"); // 按顺序执行

总结



  1. 能用:替换if/else(新手村)
  2. 用好:规则热更新+可视化(进阶)
  3. 用精:规则编排+性能优化(大师级)

曾有人问我:“规则引擎会不会让程序员失业?” 我的回答是:“工具永远淘汰不了思考者,只会淘汰手工作坊”


真正的高手,不是写更多代码,而是用更优雅的方式解决问题。



最后送句话:技术选型没有最好的,只有最合适的



最后说一句(求关注,别白嫖我)


如果这篇文章对您有所帮助,或者有所启发的话,帮忙关注一下我的同名公众号:苏三说技术,您的支持是我坚持写作最大的动力。


求一键三连:点赞、转发、在看。


关注公众号:【苏三说技术】,在公众号中回复:进大厂,可以免费获取我最近整理的10万字的面试宝典,好多小伙伴靠这个宝典拿到了多家大厂的offer。


作者:苏三说技术
来源:juejin.cn/post/7517854096175988762

0 个评论

要回复文章请先登录注册