news 2026/3/7 16:30:04

太强了!SpringBoot + QLExpress打造动态规则引擎!

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
太强了!SpringBoot + QLExpress打造动态规则引擎!

作为一名后端开发,你是否遇到过这样的场景:

运营同学说:"双11活动规则临时调整,满300减60改成满200减50,能马上上线吗?"

产品经理说:"风控策略需要微调一下,这个规则能不能今晚就生效?"

老板说:"竞品降价了,我们的VIP折扣也要调整,最好现在就能改!"

每次遇到这种情况,我们都要:修改代码 → 重新打包 → 发布部署 → 重启服务。这个流程短则半小时,长则几个小时,错过最佳时机不说,还要承担发布风险。

今天,我们来聊聊如何用动态规则引擎解决这个痛点!

01

业务痛点:规则变更的"老大难"问题

传统方式的困境

// 硬编码,修改需要重新发布 if ("GOLD".equals(userLevel) && amount >= 100) { return amount * 0.8; }

在传统的业务系统中,业务规则通常硬编码在业务逻辑中:

// 传统的硬编码方式 public BigDecimal calculateVipDiscount(String userLevel, BigDecimal price) { if ("GOLD".equals(userLevel)) { return price.multiply(new BigDecimal("0.8")); // 8折 } else if ("SILVER".equals(userLevel)) { return price.multiply(new BigDecimal("0.9")); // 9折 } return price; // 无折扣 }

这种方式存在诸多问题:

  • 响应慢:规则变更需要完整的开发流程

  • 风险高:每次发布都可能影响整个系统

  • 成本大:需要开发、测试、运维多方配合

  • 不灵活:无法快速响应市场变化

真实的业务场景

电商行业:

• 每逢大促活动,优惠规则频繁调整

• A/B测试需要不同的定价策略

• 竞品价格变动需要快速跟进

金融行业:

• 风控模型需要根据市场情况实时调整

• 利率政策变化需要快速响应

• 审核规则需要根据业务发展动态优化

内容平台:

• 推荐算法需要不断优化

• 内容审核规则需要及时更新

• 用户等级体系需要灵活调整

02

解决方案:动态规则引擎

核心思路

动态规则引擎的本质是将业务规则与业务代码分离:

  • 业务代码:负责流程控制和数据处理

  • 业务规则:以脚本形式独立存储,运行时动态执行

技术选型

本演示DEMO我选择了以下技术栈:

  • 规则引擎:QLExpress - 阿里开源

  • 后端框架:Spring Boot - 快速开发

  • 前端技术:HTML5 + TailwindCSS

03

核心实现:手把手搭建动态规则引擎

  1. 项目结构设计

springboot-dynamic-rule/ ├── entity/ │ ├── RuleScript.java # 规则实体 │ ├── OrderProcessResult.java # 订单处理结果 │ └── RuleExecuteResponse.java # 规则执行响应 ├── service/ │ ├── DynamicRuleEngine.java # 规则引擎核心 │ └── OrderService.java # 业务服务 ├── controller/ │ ├── RuleController.java # 规则管理API │ └── OrderController.java # 业务API └── resources/ └── static/ ├── index.html # 规则管理页面 └── business.html # 业务演示页面
  1. 规则引擎核心实现

@Slf4j @Service public class DynamicRuleEngine { // 内存存储规则,实际项目可使用数据库 private final Map<String, RuleScript> ruleCache = new ConcurrentHashMap<>(); private final ExpressRunner expressRunner = new ExpressRunner(); @PostConstruct public void init() { initDefaultRules(); } private void initDefaultRules() { // VIP折扣规则 addRule(new RuleScript("vip_discount", "if (userLevel == \"GOLD\") { return price * 0.8; } " + "else if (userLevel == \"SILVER\") { return price * 0.9; } " + "else { return price; }", "VIP用户折扣规则")); // 满减活动规则 addRule(new RuleScript("full_reduction", "if (totalAmount >= 200) { return totalAmount - 50; } " + "else if (totalAmount >= 100) { return totalAmount - 20; } " + "else { return totalAmount; }", "满减活动规则")); } public RuleExecuteResponse executeRule(String ruleName, Map<String, Object> params) { try { RuleScript rule = ruleCache.get(ruleName); if (rule == null || !rule.isEnabled()) { return RuleExecuteResponse.error("规则不存在或已禁用: " + ruleName); } DefaultContext<String, Object> context = new DefaultContext<>(); if (params != null) { params.forEach(context::put); } Object result = expressRunner.execute(rule.getScript(), context, null, true, false); log.info("执行规则: {}, 结果: {}", ruleName, result); return RuleExecuteResponse.success(result); } catch (Exception e) { log.error("执行规则失败: {}", ruleName, e); return RuleExecuteResponse.error("执行失败: " + e.getMessage()); } } }
  1. 业务服务集成

@Service @RequiredArgsConstructor public class OrderService { private final DynamicRuleEngine ruleEngine; public OrderProcessResult processOrder(Order order) { List<OrderProcessResult.ProcessStep> steps = new ArrayList<>(); BigDecimal currentAmount = order.getOriginalAmount(); // 1. 应用VIP折扣规则 BigDecimal discountedAmount = applyVipDiscount(order, currentAmount, steps); // 2. 应用满减规则 BigDecimal finalAmount = applyFullReduction(order, discountedAmount, steps); // 3. 计算积分奖励 Integer points = calculatePoints(finalAmount, order); return new OrderProcessResult(/* 构建返回结果 */); } private BigDecimal applyVipDiscount(Order order, BigDecimal currentAmount, List<OrderProcessResult.ProcessStep> steps) { Map<String, Object> params = new HashMap<>(); params.put("userLevel", order.getUserLevel()); params.put("price", currentAmount); RuleExecuteResponse response = ruleEngine.executeRule("vip_discount", params); if (response.isSuccess()) { BigDecimal result = new BigDecimal(response.getResult().toString()); BigDecimal reduction = currentAmount.subtract(result); // 记录处理步骤 steps.add(new OrderProcessResult.ProcessStep( "VIP折扣", "根据用户等级 " + order.getUserLevel() + " 应用折扣", currentAmount, result, reduction, "vip_discount" )); return result; } return currentAmount; } }
  1. REST API接口

@RestController @RequestMapping("/api/rules") @RequiredArgsConstructor public class RuleController { private final DynamicRuleEngine dynamicRuleEngine; @GetMapping public ResponseEntity<List<RuleScript>> getAllRules() { return ResponseEntity.ok(dynamicRuleEngine.getAllRules()); } @PostMapping public ResponseEntity<String> addRule(@RequestBody RuleScript ruleScript) { try { dynamicRuleEngine.addRule(ruleScript); return ResponseEntity.ok("规则添加成功"); } catch (Exception e) { return ResponseEntity.badRequest().body("添加失败: " + e.getMessage()); } } @PutMapping("/{ruleName}") public ResponseEntity<String> updateRule(@PathVariable String ruleName, @RequestBody RuleScript ruleScript) { try { dynamicRuleEngine.updateRule(ruleName, ruleScript); return ResponseEntity.ok("规则更新成功"); } catch (Exception e) { return ResponseEntity.badRequest().body("更新失败: " + e.getMessage()); } } @PostMapping("/execute/{ruleName}") public ResponseEntity<RuleExecuteResponse> executeRule( @PathVariable String ruleName, @RequestBody Map<String, Object> params) { RuleExecuteResponse response = dynamicRuleEngine.executeRule(ruleName, params); return ResponseEntity.ok(response); } }

操作界面

为了方便大家快速直观的体验规则引擎,DEMO提供了一套简洁的操作界面,包含规则配置与业务场景模拟。

规则管理页面

主要功能:

  • 规则列表:展示所有规则及状态

  • 在线编辑:支持规则脚本的在线修改

  • 实时测试:规则修改后立即测试效果

  • 状态控制:一键启用/禁用规则

业务演示页面

  • 订单模拟器:输入订单信息,查看处理结果

  • 详细步骤:清晰展示每个规则的执行过程

  • 处理历史:记录历史处理结果

关键前端代码:

// 动态执行规则 async function executeRule(ruleName, params) { try { const response = await fetch(`/api/rules/execute/${ruleName}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(params) }); const result = await response.json(); if (result.success) { displayResult(`执行成功!结果: ${result.result}`); } else { displayResult(`执行失败: ${result.errorMessage}`); } } catch (error) { displayResult(`请求失败: ${error.message}`); } } // 渲染处理步骤 function displayProcessSteps(processSteps) { const stepsHtml = processSteps.map((step, index) => { const beforeAmount = parseFloat(step.beforeAmount); const afterAmount = parseFloat(step.afterAmount); const reduction = parseFloat(step.reduction); return ` <div class="process-step"> <div class="step-number">${index + 1}</div> <div class="step-content"> <h4>${step.stepName}</h4> <p>${step.description}</p> </div> <div class="step-result"> <div class="amount-change">¥${beforeAmount} → ¥${afterAmount}</div> <div class="reduction">节省 ¥${reduction.toFixed(2)}</div> </div> </div> `; }).join(''); document.getElementById('processingSteps').innerHTML = stepsHtml; }

04

应用场景实战

场景1:电商平台动态定价

需求:根据用户等级和订单金额,动态计算优惠价格

传统方式

动态规则方式

// 规则脚本,可随时修改 if (userLevel == "GOLD" && totalAmount >= 100) { return totalAmount * 0.8; } else if (userLevel == "SILVER" && totalAmount >= 50) { return totalAmount * 0.9; } else { return totalAmount; }

效果对比

  • 响应速度:从小时级降低到分钟级

  • 发布风险:从系统级降低到规则级

  • 操作门槛:从开发人员扩展到业务人员

场景2:风控策略实时调整

需求:根据实时风险情况,动态调整审核策略

规则示例:

// 风控评分规则 score = baseScore; if (userAge < 18) { score = score - 20; } if (creditLevel == "HIGH") { score = score + 30; } if (monthlyIncome > 10000) { score = score + 15; } return score >= 60 ? "PASS" : "REJECT";
// 双11活动规则 if (activityType == "DOUBLE11") { if (totalAmount >= 1000) { return totalAmount - 200; } else if (totalAmount >= 500) { return totalAmount - 80; } else if (totalAmount >= 200) { return totalAmount - 30; } } return totalAmount;

业务价值

  • 快速响应:市场风险变化时立即调整

  • 精细化控制:不同场景使用不同策略

  • A/B测试:同时运行多套策略进行对比

场景3:营销活动灵活配置

需求:支持复杂的营销活动规则

规则示例

运营效果

  • 活动预热:提前配置规则,定时生效

  • 实时调整:根据活动效果实时优化

  • 快速止损:发现问题立即回滚规则

05

总结

通过将业务规则从代码中剥离出来,我们实现了:

  • 业务敏捷:规则变更从小时级提升到分钟级

  • 系统稳定:减少了系统发布频次和风险

  • 团队协作:业务人员可以直接参与规则配置

  • 成本降低:减少了开发、测试、运维的工作量

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/3 10:24:22

别再瞎选场镜(F-Theta Lens)啦!焦距、光斑、景深关系大揭秘

引言 在激光加工、激光测量等诸多先进技术领域,场镜(F-Theta Lens)作为关键的光学元件,发挥着不可或缺的作用。它能够将激光束在整个打标平面内形成均匀大小的聚焦光斑 ,确保激光能量精确地作用于目标区域,从而实现高精度的加工与测量任务。无论是精细的电子产品微加工,…

作者头像 李华
网站建设 2026/3/5 18:30:26

NMFC03多功能控制器

NMFC03 多功能控制器简介NMFC03 多功能控制器用于工业控制系统中&#xff0c;集成多种控制与处理功能&#xff0c;实现系统运行的集中管理。集成多种控制功能&#xff0c;减少系统模块数量支持多种控制逻辑与应用需求数据处理能力强&#xff0c;响应速度快可同时协调多个功能模…

作者头像 李华
网站建设 2026/3/3 10:24:28

NMFC05多功能控制器模块

NMFC05 多功能控制器模块简介 NMFC05 多功能控制器模块是一款高集成度工业控制单元&#xff0c;专为复杂自动化系统设计&#xff0c;可同时管理多路输入输出及逻辑运算。 高度集成的控制单元&#xff0c;减少系统布线和模块数量 支持多种工业协议和控制模式 能够处理复杂逻辑…

作者头像 李华
网站建设 2026/3/5 9:10:52

量化交易数据处理_Python期货数据清洗实践记录

声明&#xff1a;本文为个人学习笔记&#xff0c;仅供技术交流&#xff0c;不构成任何投资建议。 一、前言 在期货量化这条路上&#xff0c;我已经走了整整二十年。从青涩的新手到现在的老油条&#xff0c;踩过的坑数都数不清。 这些年最深刻的体会之一就是&#xff1a;数据质…

作者头像 李华
网站建设 2026/3/7 7:01:26

基于python的美妆产品网络评价的数据采集与分析2025_a0h0967b

前言   在数字化时代&#xff0c;美妆行业蓬勃发展&#xff0c;电商平台积累了海量用户评价数据。这些数据蕴含消费者偏好、产品痛点及市场趋势等核心信息&#xff0c;但传统人工分析方式效率低、覆盖面窄。基于Python的美妆产品网络评价数据采集与分析系统&#xff0c;通过自…

作者头像 李华
网站建设 2026/3/6 21:22:20

我司使用了两年的高效日志打印工具,非常好用!

为了更方便地排查问题&#xff0c;电商交易系统的日志中需要记录用户id和订单id等字段。然而&#xff0c;每次打印日志都需要手动设置用户id&#xff0c;这一过程非常繁琐&#xff0c;需要想个办法优化下。log.warn("user:{}, orderId:{} 订单提单成功",userId, orde…

作者头像 李华