从 OptaPlanner 7.x 到 8.x,我们只改了 3 个地方

发布时间:2026/11/8 21:36:24

从 OptaPlanner 7.x 到 8.x,我们只改了 3 个地方 一次“受控恐慌”后的冷静迁移一、起因一次并不严重的“事故”事情是从测试环境的一句日志开始的。那天上午测试同学反馈APS 排产偶尔点完按钮页面一直转圈。​后台日志里没有明显的Exception但有一个线程长时间处于WAITING状态。重启服务后问题消失。再跑几次又复现但概率很低。我们第一反应是“是不是 JDK 17 OptaPlanner 7.x Drools 的老问题终于爆了”老实说当时心里是有点慌的。毕竟 APS 是生产核心模块谁也不想背一个“排产算不出来”的锅。二、决策不是“大升级”而是“小修补”在翻了一圈 OptaPlanner 的 issue 和社区讨论后我们发现这个问题在 8.x 里被反复提及但没有明确的“已修复”标记7.x 官方早已停止维护但 8.x 的 API 变动看起来“可控”于是我们定了一个原则不动业务逻辑只动“不得不改”的地方。换句话说这不是一次“架构升级”而是一次“打补丁式的迁移”。三、真正改动的只有这 3 个地方事后统计我们一共改了3 个文件加起来不到 50 行代码。1️⃣ApsConstraintProviderpenalize() 变得“更数学了”这是我们最早碰到的编译错误。7.x 的老代码private Constraint capabilityConflict(ConstraintFactory constraintFactory) { return constraintFactory.from(Task.class) .filter(t - { if (t.getResourceBo() null) { return false; } if (CollUtil.isEmpty(t.getResourceBo().getCapabilityIds())) { return true; } else { return !t.getResourceBo().getCapabilityIds() .containsAll(t.getCapabilityIds()); } }) .penalize(Capability conflict, HardSoftScore.ofHard(10)); }8.x 的新写法private Constraint capabilityConflict(ConstraintFactory constraintFactory) { return constraintFactory.from(Task.class) .filter(t - { if (t.getResourceBo() null) { return false; } if (CollUtil.isEmpty(t.getResourceBo().getCapabilityIds())) { return true; } else { return !t.getResourceBo().getCapabilityIds() .containsAll(t.getCapabilityIds()); } }) .penalize(HardSoftScore.ONE_HARD) .multiply(10); }我们在 Code Review 时是怎么解释的我当时跟同事说“以前是‘一次性扣 10 分’现在是‘先扣 1 分再放大 10 倍’。”听起来像文字游戏但其实语义更清晰了ONE_HARD是一个单位惩罚.multiply(10)是权重系数以后如果要把权重放到配置中心这个写法会非常自然.multiply(penaltyConfig.getCapabilityConflictWeight())这不是语法糖这是可维护性的提升。2️⃣StartTimeUpdatingVariableListener从“地下”走到“地上”这个改动是最让我舒服的一个。7.x 的 importimport org.optaplanner.core.impl.domain.variable.listener.VariableListener; import org.optaplanner.core.impl.score.director.ScoreDirector;8.x 的 importimport org.optaplanner.core.api.domain.variable.VariableListener; import org.optaplanner.core.api.score.director.ScoreDirector;为什么这是个好信号因为impl这个包名在 Java 世界里通常意味着一句话“别碰我我随时可能变。”我们之前写VariableListener心里多少有点“偷用内部 API”的不安。现在它被挪到api包说明了一件事OptaPlanner 承认你写的这种监听器是合法扩展。这对我们这种“自己维护影子变量”的 APS 系统来说是个定心丸。3️⃣ScoreDirector字符串 → Lambda最实用这可能是日常开发中感知最强的一个变化。7.x 的写法scoreDirector.beforeVariableChanged(task, planStartTime); task.setPlanStartTime(newTime); scoreDirector.afterVariableChanged(task, planStartTime);8.x 的写法scoreDirector.beforeVariableChanged(task, Task::getPlanStartTime); task.setPlanStartTime(newTime); scoreDirector.afterVariableChanged(task, Task::getPlanStartTime);我们为什么喜欢这个改动举个真实的例子有一次我们重构Task类把字段从planStartTime改成了startTime。在 7.x 时代这类改动非常危险Java 编译器不知道你在字符串里写的是什么只有运行时才会抛异常单元测试稍不注意就漏掉但在 8.xIDE 直接标红重构字段名lambda 自动跟着改编译期就把问题拦住了我当时在群里发了一句“就冲这个 lambda这趟升级就值了。”四、迁移过程中的两个“小插曲”插曲一一开始我们以为要改很多约束打开ApsConstraintProvider看到十几个约束方法心里咯噔一下。结果发现过滤逻辑一个都没变只有penalize()的写法变了而且 IDE 的批量替换 正则就能搞定大半插曲二担心 Shadow Variable 会不会崩我们有多个影子变量CustomShadowVariable担心 8.x 会有行为变化。实际验证下来监听器触发时机一致计算逻辑无误求解结果在多个数据集上完全一致五、我们怎么验证“没改坏”迁移完成后我们没有立刻上线而是做了三轮验证回归测试用生产脱敏数据跑 100 次求解对比 7.x 与 8.x 的求解结果和分数构成性能对比平均求解时间波动在 ±5% 以内GC 行为无明显变化异常注入模拟并发提交、服务重启验证 SolverManager 行为是否一致最终结论是这次升级没有改变 APS 的任何业务语义。六、回头看这次迁移的价值是什么如果只是为了“修那个偶发线程卡死”我们其实可以只加 JVM 参数。但我们还是做了 8.x 的迁移原因有三把“隐患”往前挪了一步7.x 是死胡同8.x 至少还有社区参考为 Timefold 铺路8.x 的 API 更接近 Timefold将来迁移成本更低团队信心大家亲手改过知道“哪里会变、哪里不变”七、一句话总结从 7.x 到 8.x不是一次“冒险”而是一次“低成本、高确定性的技术避险”。如果你也在犹豫要不要升我的建议是JDK 17 下能跑就先别动真要动就只动“必须动”的地方动完之后一定要验证而不是假设
延伸阅读

更多相关文章

2026/11/8 21:36:24

1Panel 服务器运维管理

1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。它提供直观的 Web 图形界面,帮助用户轻松管理 Linux 服务器中的应用、网站、文件、数据库以及大语言模型(LLMs)等。 第一部分:1Panel 概述 一、什么是 1Panel?…

2026/10/26 20:12:17

一文搞懂出口摩洛哥必备COC认证全部要求

摩洛哥COC认证是清关的硬门槛,2025年起全面数字化。本文从法律要求、宗教禁忌、实操流程三方面拆解,帮出口商少走弯路,顺利通关。一、为什么非办不可?2020年6月起,电器、建材、玩具、纺织品等全品类强制要求COC&#x…

2026/11/8 21:32:29

开原市电工证查询系统怎么考,含金量高的证书怎么拿

开原市电工证查询系统怎么考,含金量高的证书怎么拿 你是不是也遇到过这种情况:想考电工证,但不知道去哪报名,怕被中介坑,花了几千块还拿不到证?这种焦虑在特种作业证书报考中特别常见,尤其像【开原市电工证查询系统】这类平台,很多人不知道怎么操作,…

2026/11/8 21:32:29

工地太忙根本没时间复习考试?监管办公室电工证值不值得考

工地太忙根本没时间复习考试?监管办公室电工证值不值得考 工地太忙根本没时间复习考试,这是很多一线电工的真实写照。尤其是在信阳这样的工地上,天天赶工期、扛活干,哪还有心思去琢磨考试题?但你有没有想过, 监管办公室电工证…

2026/11/8 21:32:29

电工证考试报名怎么报值不值得考 从零基础到上岗全攻略

电工证考试报名怎么报值不值得考 从零基础到上岗全攻略 实操考试心里没底怕挂科?别慌,这波我来带你稳稳上岸。电工证考试报名怎么报,是很多刚入行或者想转行的小伙伴最关心的问题,但真正能说清楚流程和细节的人不多,特别是对新手来说, 值不值得考…

2026/11/8 21:32:29

叶城县低压电工证培训多久拿证?学历不高也能顺利报考

叶城县低压电工证培训多久拿证?学历不高也能顺利报考 你是不是也担心自己学历不高,报不了低压电工证?其实,这完全不用担心。在叶城县低压电工证培训中,只要符合基本条件,学历不是主要门槛,关键是看你的实操能力和理论掌握程度。而且,整个流程并不复杂…

2026/11/8 21:32:29

考电工证有技巧吗现在?低学历也能拿证,多久拿证看这里

考电工证有技巧吗现在?低学历也能拿证,多久拿证看这里 你是不是觉得学历不够,报电工证肯定没戏?其实不然,很多从事电工工作的人都不是科班出身,照样能拿到低压电工证、高压电工证。关键是你要知道怎么操作,而不是被“学历门槛”吓退。今天就来聊聊,…

2026/11/8 21:27:29

鹤壁初级电工证过期了怎么办?郑州报考避坑指南

鹤壁初级电工证过期了怎么办?郑州报考避坑指南 证书过期了不知道怎么复审延期,这事儿真不是小事。很多人在工作中遇到证书过期的问题,不知道该怎么处理,一拖再拖,结果耽误了工作机会,甚至被单位辞退。今天就从 鹤壁初级电工证 出发,结合…

2026/11/8 0:00:27

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/8 0:00:27

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/7 14:54:47

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/7 14:50:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑