Rust 是一个日益受欢迎的 COBOL 迁移目标,适合那些希望在没有垃圾回收器的情况下同时获得内存安全和高性能的组织。对于安全关键型和性能敏感型系统而言,COBOL 迁移到 Rust 的保证极具说服力:整类内存错误在编译时就被捕获,生成的二进制文件快速且可预测。

Rust 同时也是此列表中要求最高的目标,因为它的所有权和借用模型与 COBOL 的扁平数据模型有着根本性的不同。本指南解释 COBOL 迁移到 Rust 实际涉及什么、英国企业可用的方法、成本如何,以及如何管理风险。

要点(TL;DR)

  • Rust 适合内存安全和性能都很重要的 COBOL 迁移,没有垃圾回收器,也没有运行时开销
  • Rust 的所有权和借用模型是决定性的挑战:COBOL 扁平的 WORKING-STORAGE 必须被重新表达为拥有所有权的 Rust struct,而不与 borrow checker 对抗
  • Rust 没有原生的十进制类型;金融字段需要一个像 rust_decimal 这样的 crate,而不是 f64
  • 中等规模的迁移通常花费 200,000800,000 英镑,耗时一到两年;预计相比托管语言目标,所有权模型会增加设计工作量

为何为 COBOL 迁移选择 Rust

Rust 是针对一组特定需求的审慎选择:

无需垃圾回收器的内存安全。 Rust 的所有权系统在编译时保证内存安全,没有托管运行时那种引发停顿的垃圾回收。对于正确性和可预测延迟都很重要的系统而言,这是一个真正的优势。

性能。 Rust 编译为原生代码,性能可与 C 和 C++ 相媲美,适合 COBOL 系统常常承担的繁重批处理和事务工作负载。

可靠性。 编译器的严格性意味着许多在其他语言中会进入生产环境的错误,在 Rust 中根本无法编译。对于安全关键型系统,这种前期的严格性会在系统的整个生命周期中获得回报。

可移植性。 Rust 在其支持的任何平台上运行,并能干净地部署到 Linux 服务器和容器。

所有权模型才是真正的工作

这是最能将 Rust 迁移与 Java、C# 或 Python 迁移区分开来的一点。COBOL 使用扁平的 WORKING-STORAGE 节,其中每个数据项在程序内都可全局访问,处处存在隐式共享状态。Rust 强制执行严格的所有权和借用:每个值都有唯一的所有者,访问由 borrow checker 管理。

一次正确的迁移会将 COBOL 的数据模型重新表达为拥有所有权、具有显式访问模式的 Rust struct 类型,而不是试图重建 COBOL 的全局可变状态(那会在每一步都与 borrow checker 对抗)。这是设计工作,而非机械翻译,这也是为何 Rust 迁移通常比托管语言目标带来更多前期架构工作量。自动转换能让你得到可编译、结构正确的 Rust;而将其打磨成惯用的、对 borrow checker 友好的 Rust,则需要人类专业知识。

十进制精度这一点

与 Go 一样,Rust 没有原生的十进制类型。COBOL 的 PIC 9COMP-3 字段保存精确的十进制值,将它们映射到 f64(IEEE 754 二进制浮点)会在金融计算中引入舍入误差。对于任何货币或对十进制敏感的逻辑,请使用像 rust_decimal 这样的 crate,而不是 f64。将每个十进制字段视为一个审慎的决定。希望在不增加额外依赖的情况下获得精确十进制运算的组织,有时更偏爱 C# (原生 decimal)或 JavaBigDecimal)。

需要真正翻译的 COBOL 构造

一次安全的迁移会将 COBOL 的语义翻译为惯用的 Rust:

  • 组项成为具有拥有所有权、有类型字段的 Rust struct 类型。
  • PIC 子句映射到正确的 Rust 类型:字母数字用 String,按位数区分的数值用 i16 / i32 / i64,十进制字段用十进制 crate(在精度不重要时用 f64)。
  • EVALUATE / WHEN 自然地映射到 Rust 的 match 表达式。
  • PERFORM 范围成为函数调用;段落和节分解为函数。
  • COPYREPLACE(copybook)必须被解析,包括嵌套的 copybook。
  • EXEC SQL(DB2)、EXEC CICS 和 VSAM 需要重新设计到 Rust 数据库 crate(例如 sqlxdiesel)和现代服务模式上。
  • EBCDIC 编码和定宽布局需要显式转换为 UTF-8 以及有类型的模型。

迁移方法

有三种主要方法,各有不同的风险和成本特征。

1. 自动转换

工具解析 COBOL 并生成 Rust,为组项生成 struct、带大小的整数类型,以及为 EVALUATE 生成 match 表达式。Mecanik COBOL 迁移到 Rust 工具 使用完整的编译器流水线,生成可编译的 Rust 以及一份标记出嵌入式 SQL、CICS 交互、动态调用和十进制精度字段的 Migration Report。

最适合: 在重构为惯用的、具有所有权意识的设计之前,快速建立一个可编译的 Rust 基线。

风险: 生成的 Rust 结构正确,但不会自动符合惯用法;所有权重构和十进制决策是人类的工作。

2. 并行重写

Rust 系统与 COBOL 系统并行运行,两者处理相同的输入,输出相互验证,直到 Rust 通过且 COBOL 退役。

最适合: 无法冒险中断连续性的任务关键型和安全关键型系统。

风险: 并行运行两个系统会使迁移期间的运营成本翻倍,并要求有纪律的对账。

3. 增量迁移(Strangler Fig)

COBOL 程序被逐个替换为 Rust 等价物。系统先成为混合体,最终成为纯 Rust。

最适合: 完全重写不切实际的大型单体 COBOL 系统。

风险: 混合状态可能比计划持续更久,并要求谨慎的接口设计。

对于大多数英国迁移,strangler fig 方法结合选择性的自动转换,能在风险和速度之间提供最佳平衡。

英国的 COBOL 迁移到 Rust 成本

成本在很大程度上取决于代码库规模、复杂性和方法。英国企业项目的指示性区间:

系统规模方法估计成本
小型(< 50,000 行)并行重写80,000 至 200,000 英镑
中型(50,000 至 500,000 行)Strangler fig200,000 至 800,000 英镑
大型(500,000+ 行)自动化 + 增量重构500,000 至 2,000,000+ 英镑
遗留主机退役完整项目1,000,000 至 10,000,000+ 英镑

这些数字涵盖分析、迁移、测试和上线支持,不包括持续运营成本、培训和下游集成工作。由于所有权模型带来的额外设计工作量,对于给定规模,Rust 迁移往往趋向这些区间的上端。

Mecanik COBOL 迁移到 Rust 服务 专注于安全关键型和性能敏感型迁移。对于权衡目标语言的组织,COBOL 迁移概览 列出了包括 C#、Java、Python、Go 和 C++ 在内的完整范围。对于从 IBM z/OS 迁出的迁移,遗留主机迁移服务 涵盖基础设施退役以及代码迁移。

主要风险及应对方法

所有权模型。 决定性的 Rust 风险。为将 COBOL 的扁平状态重新表达为拥有所有权的 struct 预留设计时间。试图对全局可变状态进行字面直译会导致与 borrow checker 的对抗。

十进制精度。 审查 Migration Report 中标记的每个十进制字段,并在上线前对金融字段使用 rust_decimal(或类似方案)。

未记录的业务逻辑。 数十年嵌入的业务规则,却没有外部文档。发现和记录是任何迁移中最耗时、风险最集中的部分。

数据访问层。 针对 DB2 的 EXEC SQL 和 VSAM 处理必须重新设计到 Rust 数据库 crate 上。这通常是所有权重构之后最大的单项工作。

团队技能。 Rust 的学习曲线比托管语言更陡峭。请把团队的上手时间或专家支持考虑在内。

回归测试和切换。 通过在真实(匿名化)数据上进行全面回归测试,证明 Rust 输出与 COBOL 匹配,并规划带有回滚和对账的切换。

关键要点

  • Rust 适合内存安全和性能都很重要的 COBOL 迁移,没有垃圾回收器。
  • 所有权和借用模型是决定性的挑战;请为设计工作量做规划,而不仅是翻译。
  • Rust 没有原生的十进制类型;对金融字段使用 rust_decimal,而非 f64
  • 大多数英国企业项目采用带有选择性自动化的 strangler fig 方法,且 Rust 迁移比托管语言目标带来更高的前期设计成本。

常见问题(FAQ)

为何为 COBOL 迁移选择 Rust 而非 C++? 两者都是非托管的高性能目标。Rust 增加了 C++ 不强制的编译时内存安全保证,这对安全关键型系统很有价值。C++ 可能适合已有 C++ 代码库和专业知识的团队。两者都位于目标语言谱系中以性能为重的一端。

COBOL 迁移到 Rust 最难的部分是什么? Rust 的所有权和借用模型。COBOL 扁平的、可全局访问的 WORKING-STORAGE 必须被重新表达为拥有所有权、具有显式访问模式的 Rust struct。这是自动转换无法完全替你完成的设计工作。

Rust 如何处理 COBOL 的压缩十进制字段? Rust 没有原生的十进制类型,因此十进制字段默认回退到 f64,这可能在金融计算中引入舍入。对货币逻辑使用像 rust_decimal 这样的 crate。好的转换器会标记每个十进制字段,以便你逐个字段做决定。

COBOL 逻辑能自动转换为 Rust 吗? 可以,借助工具。好的转换器会生成带有 struct、带大小整数和 match 表达式的可编译 Rust,并标记嵌入式 SQL、CICS 交互、动态调用和十进制字段。朝惯用 Rust 的所有权重构仍然是人类的工作。

COBOL 迁移到 Rust 需要多长时间? 小型、文档完善的系统需要四到十二个月。中型企业系统需要十二到三十个月。大型主机项目的完全退役可能需要三到五年。相比托管语言目标,Rust 通常会增加设计时间。