OptaPlanner 7.x → 8.x 升级 Checklist

适用场景:APS / 排程系统、使用 ConstraintStream 或 Drools DRL、依赖实时规划(Real-time Planning)

参考来源:OptaPlanner 发展方向与问题


一、升级前评估(必做)

  • 确认当前版本

    • 当前 OptaPlanner 版本:_______(例如 7.44.0.Final)

    • 是否使用 Drools DRL 评分:✅ 是 / ❌ 否

    • 是否使用链式规划(@PlanningChain/ PlanningVariable(graphType = CHAINED)):✅ 是 / ❌ 否

    • 是否使用 VariableListener:✅ 是 / ❌ 否

    • 是否使用实时规划(SolverManager.addProblemChange()):✅ 是 / ❌ 否

  • 确认目标版本

    • 计划升级到:8.___.Final

    • Spring Boot 版本是否 ≥ 2.7(8.x 最低要求)

  • 阅读官方迁移指南

    • OptaPlanner 8 Migration Guide

    • 重点关注 ConstraintStream 与 Drools 的生命周期说明

二、依赖与构建配置

  • 升级 OptaPlanner BOM / Dependency
XML 复制代码
<dependency>
  <groupId>org.optaplanner</groupId>
  <artifactId>optaplanner-core</artifactId>
  <version>8.x.x.Final</version>
</dependency>
  • 移除或升级 Drools 相关依赖

    • 若计划保留 Drools:确认 optaplanner-drools版本一致

    • 若计划迁移:移除 optaplanner-drools、kie-ci等依赖

  • 清理本地构建缓存

    • Maven:mvn clean

    • Gradle:gradle clean build --refresh-dependencies


三、API 迁移(核心修改)

1. ConstraintProvider(ApsConstraintProvider.java)

  • penalize / reward 方法签名调整
java 复制代码
// 7.x
.penalize("超时惩罚", HardSoftScore.ONE_HARD);

// 8.x
.penalize(HardSoftScore.ONE_HARD)
.asConstraint("超时惩罚");
  • 统一约束命名规则

    • 所有约束均以 asConstraint("xxx")结尾

    • 避免匿名约束,便于调试与分数分析

  • 验证所有 ConstraintStream 流

    • from()/ join()/ ifExists()行为是否变化

    • 是否存在因类型推断导致的编译错误


2. VariableListener 包路径变更

  • 修改 import 语句
java 复制代码
// 7.x
import org.optaplanner.core.impl.domain.variable.listener.VariableListener;
import org.optaplanner.core.impl.score.director.ScoreDirector;

// 8.x
import org.optaplanner.core.api.domain.variable.VariableListener;
import org.optaplanner.core.api.score.director.ScoreDirector;
  • 检查所有自定义 VariableListener

    • 文件名示例:*VariableListener.java

    • 确认无 impl包残留引用


3. ScoreDirector API 变更

  • 字符串属性名 → 方法引用
java 复制代码
// 7.x
scoreDirector.beforeVariableChanged(entity, "planStartTime");
scoreDirector.afterVariableChanged(entity, "planStartTime");

// 8.x
scoreDirector.beforeVariableChanged(entity, Entity::getPlanStartTime);
scoreDirector.afterVariableChanged(entity, Entity::getPlanStartTime);
  • 全局搜索关键词

    • beforeVariableChanged

    • afterVariableChanged

    • variableChanged


四、实时规划(Real-time Planning)适配

1. ProblemChange 接口统一

  • 确认所有实时变更逻辑已迁移到 ProblemChange
java 复制代码
public class AddTaskProblemChange implements ProblemChange<Schedule> {
    @Override
    public void doChange(Schedule schedule, ScoreDirector<Schedule> scoreDirector) {
        // ...
    }
}
  • 移除旧版实时规划相关代码

    • Solver.addEntity()

    • Solver.removeEntity()

    • Solver.addProblemFact()


2. SolverManager Problem ID 治理(⚠️ 重要)

参考博文:SolverManager 存在 Problem ID 复用异常问题

  • 平台侧接管 Problem ID 生成

    • 客户端传入业务 ID(如 orderId)

    • 平台生成内部 problemId(UUID / 自增 ID)

  • 接口层改造

    • 启动规划:返回内部 problemId

    • 查询 / 终止 / 实时变更:使用内部 problemId

  • 增加 Problem ID 清理机制

    • 规划完成后主动调用 solverManager.close(solverJobId)

    • 避免异常中断导致状态残留


五、链式规划与新特性评估

1. 现有链模型(CHAINED)

  • 暂不迁移到 @PlanningListVariable

    • 确认当前链模型运行稳定

    • 8.x 新链模型尚未完全成熟(参考博文)

  • 验证 Shadow Variable 行为

    • @CustomShadowVariable监听器是否正常触发

    • 时间计算逻辑是否与之前一致


2. 新特性试用(可选)

  • @PlanningListVariable(仅限新模块)

    • 明确标注为"实验性功能"

    • 准备回退方案

  • @IndexShadowVariable

    • 仅在非核心链路中试用

六、Drools DRL 迁移(长期必做)

Drools DRL 将在 OptaPlanner 9.x 移除

  • 制定 DRL → ConstraintStream 迁移计划

    • 优先级:核心约束 > 次要约束 > 调试约束
  • 增量迁移

    • 每次迁移 1--2 条约束

    • 对比新旧分数结果一致性

  • 或评估 Incremental Java Score Calculation

    • 性能要求极高时考虑

    • 实现成本较高(参考博文)


七、测试与验证

  • 单元测试

    • 所有 ConstraintProvider 测试通过

    • 边界条件(空集合、单实体)验证

  • 集成测试

    • 典型业务场景全量规划

    • 实时规划(添加 / 删除任务)验证

  • 回归测试

    • 与 7.x 在相同数据集上运行

    • 对比解的质量与分数构成

    • 允许分数结构变化,但业务结果应一致

  • 性能测试

    • 规划耗时是否显著增加

    • GC / CPU 使用率是否在可接受范围


八、部署与回滚预案

  • 灰度发布

    • 先在非核心业务线启用 8.x

    • 观察 1--2 个迭代周期

  • 回滚方案

    • Git tag / 分支保留 7.x 稳定版本

    • 数据库 schema 无破坏性变更(如有需单独处理)

  • 监控增强

    • Solver 执行时长监控

    • Problem ID 泄漏检测

    • 异常 SolverJob 自动清理


九、升级完成确认

  • 所有 javax.*/ impl包引用已清除

  • 所有约束均有 asConstraint()命名

  • 实时规划功能经生产流量验证

  • 团队已了解 8.x API 变化点

  • 文档已更新(架构图、API 说明)


附录:常见搜索关键词(用于全局替换)

java 复制代码
beforeVariableChanged
afterVariableChanged
VariableListener
ScoreDirector
penalize(
reward(
impl.domain.variable
impl.score.director

✅ 预计修改工作量:2--3 小时

✅ 主要风险点:SolverManager Problem ID 管理、新链模型成熟度

✅ 推荐节奏:先升级 + 稳定 API,再逐步迁移 Drools

复制代码
相关推荐
Yyyyyy~3 分钟前
[Mysql] 数据类型
数据库·mysql
FITA阿泽要努力4 分钟前
第 1 周·第 3 讲|工具如何交给模型:工具定义、参数与结构化调用
服务器·数据库·python·agent
需要82610 分钟前
缓存与数据库一致性:延迟双删与订阅 binlog 的取舍
数据库·缓存
省钱兄--zs13 分钟前
24小时自助健身房系统软件开发实战:从架构设计到部署全指南
java·数据仓库·spring boot·系统架构·需求分析
IT研究室17 分钟前
最新计算机毕业设计选题推荐-基于spring boot的智慧教学资源管理与互动交流平台-网站-文档指导-Java-springboot
java·spring boot·课程设计
蜗牛互联网19 分钟前
Java HttpClient 调用 Gemini 图像理解与金额字段校验
java·开发语言·人工智能·后端·python
开开心心就好19 分钟前
视频里的图片怎么提取?双击一下就导出
java·前端·人工智能·spring·智能手机·intellij-idea·excel
蜗牛互联网21 分钟前
Python Responses API视觉输入与本地金额校验最小实现
java·开发语言·人工智能·后端·python
程序猿_极客23 分钟前
【免费】分享一套优质的基于Java的智慧养老院管理系统的设计与实现(带可视化),源码+文档+视频详解(讲解)
java·spring boot·后端·养老院管理系统
眼不痛请看我32 分钟前
Ubuntu_22.04_LTS虚拟机安装指南
linux·数据库·ubuntu