实录⑤:2 天从停止支持的服务器中救出

AI 导入案例

「因为还在跑,所以别去碰它」。一直被这样念叨着的系统,回过神来才发现,它仍以 10 年前的模样运行在公司业务的核心位置——想必许多企业都有似曾相识之感。这次要讲的,是一套 2016 年发布的项目管理系统,在一台 2020 年就已停止支持的操作系统上,一直对互联网公开着,从这样的状态出发,将其迁移至最新环境的实录。实际工时 2 天。3,623 张工单、4.0GB 附件,一条不缺地全部承接了下来。

「因为还在跑所以不敢碰」,这一状态已经持续了 10 年。

对象是公司内部的项目管理系统(Redmine)。项目进展、故障处理记录、与客户往来的来龙去脉——10 年的积累都沉淀在这里。这正是一套因为停不下来所以不敢碰的系统。

然而一查看内部情况,就会发现它绝非一个可以放任不管的状态。

项目迁移前迁移后
OSCentOS 6.10
(2020 年停止支持)
AlmaLinux 10.1
应用Redmine 3.2.1(2016 年)Redmine 6.1.3
运行环境Ruby 2.2.4Ruby 3.3.10
数据库MySQL 5.7MariaDB 10.11
Web 服务器Apache 2.2 + Passengernginx 1.26 + puma

操作系统停止支持已 6 年。在这期间公开的漏洞修复,一个都没有被应用。而它就在可从公司外部访问的状态下持续运行着。并不是「因为还在跑所以安全」,「只是还在跑而已,并没有受到保护」才是更准确的说法。

遗留系统真正的风险,并不在于「总有一天会坏掉」。
而在于它虽没坏,却唯独防护早已停摆。

迁移的成败,在着手之前的实测阶段就已注定。

进入迁移之前,我们先用数字把现状摸清。结果证明,正是这一步在很大程度上左右了工时。

  • 数据库 38MB/附件 4.0GB
  • 每天 20~30 次请求=仍在实际使用中
  • 扩展插件:零。自定义设计:无

最后一行是决定性的。这类迁移中最容易起波折的,正是后来加装的扩展功能能否在新版本上运行。一旦跑不起来,就只剩「另寻替代」「放弃该功能」「自己动手修」这三个选择,几周时间就此蒸发。而这次,这道障碍从一开始就不存在。

基于这份实测,我们在着手前定下了三条方针。

1. 放弃了逐级升版本的做法

最初我们是以 3.2 → 4.2 → 5.1 → 6.x 逐级升级为前提来估算的。然而经过验证发现,可以一次性跨越 10 年直接更新到位。原本预估的工时因此整块变得不再需要。

2. 没有更换数据库的种类

为了与其他系统在运维上保持一致,也曾有过迁往另一种数据库产品的方案。但由于迁移源的数据格式不同,中间必须插入转换处理。对于 3,623 张工单、6,071 条历史这类「即便丢了也不容易察觉的数据」,绝不引入转换这样的风险。比起运维的统一,我们更优先保证数据一条都不缺失。

3. 没有对现有服务器进行原地升级

另行准备了一台新服务器,切换时只需改写入口配置的一行。即便失败,只要改回那一行就能恢复原样——为的是把这样的状态一直维持到最后。

真正耗费时间的,并不是 Redmine。

从这里开始才是实操。把迁移途中踩到的问题一一列出,趋势便清晰地浮现出来。

旧服务器与新服务器,根本无法通信OS最新的操作系统以不安全为由,拒绝旧世代的加密方式。连搬运 4GB 文件的手段都没有,迁移就是从这样的起点开始的。我们在旧服务器一侧临时开了一个交接口,结束后随即关闭以作应对。
10 年份的版本升级,一次就通过了应用由于 Redmine 保留了过去所有的更新步骤,得以不经过中间版本直接升到最新版。57 项更新处理无一报错,全部完成。正因为扩展功能为零才得以成立的捷径。
所需的部件不包含在标准配置中应用用于与 Web 服务器对接的部件并未随 Redmine 本体一同附带。我们将其追加到不会被日后版本升级覆盖的官方扩展位中,从而解决。
即便把权限全部开放,仍被「没有权限」所拒绝OS操作系统的安全机制,在有别于文件权限的另一个层面上阻断了通信。无论怎么放宽权限设置都无法解决的典型例子。通过更改连接方式本身来应对。
刚一登录就提示「未找到页面」通信路径路径上的两台服务器相互覆盖了同一份信息,导致加密通信的信息丢失。应用本身正常,唯独转发目标不存在,是一种让人摸不着头脑的故障。
通知邮件因证书错误而发不出去加密由于是以 IP 地址进行连接的,与证书的名义不一致。没有靠关闭验证来回避,而是定义了与证书相符的名称,在保持验证开启的状态下解决。
阻止密码暴力破解的功能,标准配置中没有应用Redmine 没有「失败达规定次数即锁定」的标准功能。我们在 Web 服务器一侧限制尝试次数以作加固。一旦阻断的位置搞错,就会把全体员工都挡在门外,因此正确识别真实访问来源的配置是前提。
与源代码的对接,依赖于旧服务器外部对接原本是直接引用旧服务器内文件的配置,一迁移就全部失效。我们做了一套从公司内部 Git 服务器自动复制的机制,每 15 分钟更新一次。原本处于冻结状态的对接,反而因此复活了。

8 个问题当中,源于 Redmine 本体的仅有 3 个。而且其中 1 个还是「比想象中简单」这样一个令人惊喜的误判。真正让人费神的,其实只有 2 个。

其余的则是操作系统的代际差异、安全机制、通信路径、加密、外部系统对接——全都在应用程序的外部。

吞噬遗留系统迁移工时的,并不是应用本身。
而是 10 年间积累下来的「周边环境的差异」。

「一行即可回退」这一点,直到最后都不撒手。

切换时,只需把入口服务器的转发目标指向新服务器。回退时也是一行。并且,旧环境不做停机,就让它照常运行地保留着。

切换当天,「照常运行的旧环境」与「照常运行的新环境」并存,保持着一行即可在两者之间往返的状态。放置数日、确认没有问题之后,才停掉旧的一侧。

把「切换」与「旧环境的停机」分在不同的日子进行。仅此一点,就能改变当天的判断。只要清楚一旦有事就能回退,便无需在原因不明的情况下慌忙叠加应急处理。迁移作业中代价最高的,正是在无法回头的状态下惊慌失措

不止于迁移,还补上了 10 年份的欠缺。

在新环境中,我们同时补齐了旧环境所没有的东西。

  • 每日备份(保留 7 代) — 旧环境连备份机制本身都没有
  • 访问来源的记录 — 迁移前所有访问看上去都一模一样,处于无法追查谁从哪里来的状态
  • 登录尝试的限制 — 因无标准功能,在 Web 服务器一侧加以补强
  • 源代码对接的自动更新 — 让事实上已冻结的对接变为每 15 分钟更新一次

最终承接下来的数据如下所示。我们已确认旧环境与新环境的条数完全一致。

21项目
3,623工单
6,071处理历史
4.0GB附件(丢失 0)

来自外部系统的对接,也无需更改配置便照常运行。在用户看来,不过是登录界面换新了而已——作为一次迁移,这是理想的落地。

如果「我们这儿也有同样的服务器」。

这次迁移之所以能在短时间内完成,原因可归结为三点。

  • 没有安装扩展功能——所以才能一次跨越 10 年
  • 着手前做了实测——判断的依据以数字的形式备齐
  • 始终保持可回退的状态——切换当天无需去赌一把

反过来说,这三点在着手之前都是可以确认的。「一套停不下来的系统,正跑在一台已停止支持的服务器上」——如果您有似曾相识之感,不妨先从用数字掌握现状开始与我们商谈。能不能迁,通常查一查就知道。

本公司提供对那些仍运行在已停止支持的操作系统、老旧框架之上的业务系统进行迁移与革新的支持服务。
现状调查(版本、数据量、有无扩展功能、公开范围)免费。可与遗留系统的革新(AI Re: Platform/简称:AIR Platform)一并,欢迎立即咨询。

咨询表单(请注明「希望咨询遗留系统迁移」)/ info@flagship-ai.jp

系列「Legacy to AI 实录」

※本文中的数据为截至 2026 年 8 月的实测值。迁移所需的周期与工作咨询内容因系统的架构、有无扩展功能而异。

分类:

标签:

🌐 简体中文