三角洲辅助卡盟新版上线,应有尽有
当前位置:首页 > 游戏攻略> 正文

植木的法则植木耕助

发布时间:06/21 11:03:25
植木耕助的法则:从零构建高可用规则引擎的实战指南

一、环境准备与核心依赖安装

在开始构建规则引擎前,你需要一个干净的开发环境。我们将使用Java作为后端语言,Spring Boot作为框架。

1.1 基础环境配置

确保你的机器上已经安装了以下软件,并配置好环境变量。

  • Java 11或更高版本:在终端执行java -version验证。
  • Maven 3.6+:执行mvn -v验证。
  • IDE(如IntelliJ IDEA或Eclipse):本文使用IDEA社区版。

1.2 创建Spring Boot项目并引入依赖

打开IDEA,通过Spring Initializr创建一个新项目,或使用以下命令生成:

curl https://start.spring.io/starter.zip -d dependencies=web,data-jpa,h2 -d javaVersion=11 -d type=maven-project -d bootVersion=2.7.0 -o rule-engine.zip

解压后,用IDEA打开项目。在pom.xml文件中,添加规则引擎核心依赖:

<dependency> <groupId>org.jeasy</groupId> <artifactId>easy-rules-core</artifactId> <version>4.1.0</version> </dependency> <dependency> <groupId>org.jeasy</groupId> <artifactId>easy-rules-mvel</artifactId> <version>4.1.0</version> </dependency>

保存文件,IDEA会自动下载依赖。如果使用命令行,执行mvn clean install

二、定义你的第一条业务规则

规则引擎的核心是“规则”。我们以一个电商折扣场景为例,当用户订单金额满100元时,自动减免10元。

2.1 创建规则实体类

src/main/java/com/example/ruleengine/model目录下,创建Order.java

package com.example.ruleengine.model; public class Order { private String orderId; private Double amount; private Double discount = 0.0; // 生成Getter和Setter方法(此处省略,实际开发中请使用Lombok或手动生成) public String getOrderId() { return orderId; } public void setOrderId(String orderId) { this.orderId = orderId; } public Double getAmount() { return amount; } public void setAmount(Double amount) { this.amount = amount; } public Double getDiscount() { return discount; } public void setDiscount(Double discount) { this.discount = discount; } }

2.2 实现具体的规则逻辑

src/main/java/com.example.ruleengine.rule目录下,创建OrderDiscountRule.java

package com.example.ruleengine.rule; import com.example.ruleengine.model.Order; import org.jeasy.rules.annotation.Action; import org.jeasy.rules.annotation.Condition; import org.jeasy.rules.annotation.Rule; @Rule(name = “订单满减规则”, description = “当订单金额大于等于100元时,减免10元”) public class OrderDiscountRule { @Condition public boolean when(Order order) { // 条件判断:订单金额是否 >= 100 return order.getAmount() != null && order.getAmount() >= 100; } @Action public void then(Order order) { // 执行动作:应用折扣 order.setDiscount(10.0); System.out.println(“规则触发:订单” + order.getOrderId() + “符合满减条件,已减免10元。”); } }

关键点@Condition方法必须返回布尔值,@Action方法执行具体操作。方法参数Order order是引擎传入的事实对象。

三、组装并执行规则引擎

规则定义好后,需要将它们注册到引擎中,并传入事实数据触发计算。

3.1 创建规则引擎配置类

src/main/java/com.example.ruleengine/config目录下,创建RuleEngineConfig.java

package com.example.ruleengine.config; import org.jeasy.rules.api.RulesEngine; import org.jeasy.rules.core.DefaultRulesEngine; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RuleEngineConfig { @Bean public RulesEngine rulesEngine() { // 创建规则引擎实例,可配置参数 RulesEngine rulesEngine = new DefaultRulesEngine(); // 可以在此处设置引擎参数,例如: // ((DefaultRulesEngine) rulesEngine).setSkipOnFirstAppliedRule(true); return rulesEngine; } }

3.2 编写服务类触发规则执行

src/main/java/com.example.ruleengine/service目录下,创建RuleEngineService.java

package com.example.ruleengine.service; import com.example.ruleengine.model.Order; import com.example.ruleengine.rule.OrderDiscountRule; import org.jeasy.rules.api.Facts; import org.jeasy.rules.api.Rules; import org.jeasy.rules.api.RulesEngine; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class RuleEngineService { @Autowired private RulesEngine rulesEngine; public Order applyRules(Order order) { // 1. 创建事实集合,放入需要判断的数据对象 Facts facts = new Facts(); facts.put(“order”, order); // “order”是事实名称,在复杂规则中用于引用 // 2. 创建规则集合,并注册我们定义的规则 Rules rules = new Rules(); rules.register(new OrderDiscountRule()); // 3. 触发规则引擎执行 rulesEngine.fire(rules, facts); // 4. 返回处理后的订单对象 return order; } }

四、创建REST接口进行测试

为了验证规则引擎是否工作,我们创建一个简单的HTTP接口。

4.1 创建控制器

src/main/java/com.example.ruleengine/controller目录下,创建OrderController.java

package com.example.ruleengine.controller; import com.example.ruleengine.model.Order; import com.example.ruleengine.service.RuleEngineService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController public class OrderController { @Autowired private RuleEngineService ruleEngineService; @PostMapping(“/api/order/applyRules”) public Order applyRules(@RequestBody Order order) { // 直接调用服务层,触发规则计算 return ruleEngineService.applyRules(order); } }

4.2 使用工具进行接口测试

启动Spring Boot应用(运行Application类的main方法)。使用Postmancurl命令测试:

  • 请求URL:POST http://localhost:8080/api/order/applyRules
  • 请求头:Content-Type: application/json
  • 请求体(JSON):
{ “orderId”: “ORD202309280001”, “amount”: 150.0 }

你将收到如下响应,表示规则已生效:

{ “orderId”: “ORD202309280001”, “amount”: 150.0, “discount”: 10.0 }

同时,在应用控制台会看到打印的日志:“规则触发:订单ORD202309280001符合满减条件,已减免10元。”

五、进阶:实现动态规则与规则优先级

静态编码的规则不便于管理。接下来,我们将规则配置到数据库,实现动态加载。

5.1 设计规则表结构

src/main/resources/schema.sql中创建表(使用H2内存数据库):

CREATE TABLE business_rule ( id BIGINT AUTO_INCREMENT PRIMARY KEY, rule_name VARCHAR(100) NOT NULL, rule_condition VARCHAR(500) NOT NULL, rule_action VARCHAR(500) NOT NULL, priority INT DEFAULT 0, enabled BOOLEAN DEFAULT true );

插入一条规则数据到src/main/resources/data.sql

INSERT INTO business_rule (rule_name, rule_condition, rule_action, priority) VALUES (‘VIP用户折扣规则’, ‘order.getAmount() > 200 && order.getUserLevel().equals(“VIP”)’, ‘order.setDiscount(order.getDiscount() + 20.0);’, 1);

5.2 从数据库加载并注册规则

创建一个新的服务类DynamicRuleService.java

package com.example.ruleengine.service; import org.jeasy.rules.api.Rule; import org.jeasy.rules.core.RuleBuilder; import org.jeasy.rules.mvel.MVELRuleFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import java.util.List; import java.util.Map; @Service public class DynamicRuleService { @Autowired private JdbcTemplate jdbcTemplate; @Autowired private RulesEngine rulesEngine; private Rules dynamicRules = new Rules(); @PostConstruct // 应用启动时加载规则 public void loadRulesFromDB() { String sql = “SELECT rule_name, rule_condition, rule_action, priority FROM business_rule WHERE enabled = true”; List<Map<String, Object>> ruleList = jdbcTemplate.queryForList(sql); for (Map<String, Object> row : ruleList) { String name = (String) row.get(“rule_name”); String condition = (String) row.get(“rule_condition”); String action = (String) row.get(“rule_action”); int priority = (Integer) row.get(“priority”); // 使用MVEL表达式引擎构建规则 Rule rule = new RuleBuilder() .name(name) .when(condition) // MVEL表达式字符串 .then(action) // MVEL表达式字符串 .priority(priority) .build(); dynamicRules.register(rule); } } public void fireDynamicRules(Facts facts) { rulesEngine.fire(dynamicRules, facts); } }

注意:使用MVEL规则时,确保事实对象(如order)的属性在表达式上下文中可访问。你需要在applyRules方法中调用fireDynamicRules,并确保Order类有userLevel属性。

六、生产环境部署与监控要点

将规则引擎投入生产环境,需注意以下几点。

6.1 性能与线程安全

  • 规则引擎实例:建议使用@Scope(“prototype”)为每个请求或线程创建独立的引擎实例,避免状态共享问题。
  • 规则缓存:动态规则从数据库加载后,应放入本地缓存(如Caffeine),设置合理的过期时间,避免频繁查询数据库。

6.2 规则版本管理与回滚

business_rule表中增加字段:version(版本号)、publish_time(发布时间)。发布新规则时,插入一条新记录并更新版本号。在服务层,始终加载最新生效版本的规则。出现问题需回滚时,只需将旧版本规则的enabled设为true,新版本设为false即可。

6.3 日志与监控

RuleEngineConfig中配置规则引擎监听器,记录每次规则触发的详细信息:

DefaultRulesEngine rulesEngine = new DefaultRulesEngine(); rulesEngine.registerRuleListener(new RuleListener() { @Override public void onSuccess(Rule rule, Facts facts) { log.info(“规则 [{}] 执行成功, 事实: {}”, rule.getName(), facts); } });

将日志接入ELK(Elasticsearch, Logstash, Kibana)或类似监控系统,便于问题排查和规则效果分析。

至此,一个具备核心功能、支持动态配置、可直接用于生产环境的规则引擎已构建完成。你可以根据业务需求,定义更多的@Condition@Action,或集成更复杂的Drools等引擎,其架构思想与此一脉相承。

版权保护: 本文由 741卡盟 原创,转载请保留链接: http://741ka.com/gamenews/23178.html