这篇文章讲述了一个关于**“给老古董穿上高科技新鞋”**的故事。
想象一下,Bankdata(丹麦的一家大型银行 IT 服务商)就像是一个拥有百年历史的**“金融帝国”。这个帝国里运行着许多至关重要的系统,它们是用一种叫COBOL的古老语言编写的。COBOL 就像是一种“古典拉丁语”**,虽然古老,但极其精准、可靠,至今仍在处理着数以亿计的资金交易。
然而,这个帝国面临着一个大麻烦:他们用来管理这些古老系统的**“流水线”(CI/CD 管道),就像是一个摇摇欲坠的、由旧木箱和胶带拼凑起来的传送带**。
1. 旧系统的问题:像是一个“随时会散架的乐高城堡”
在迁移之前,Bankdata 的自动化流程(用来测试和部署代码的工具)存在几个大问题:
- 太依赖特定平台(Vendor Lock-in): 他们的流水线是专门为Jenkins(一种自动化服务器)定制的。这就像是你造了一辆车,但它的引擎只能加一种特定品牌的汽油,而且只能在特定的加油站(Jenkins)里才能启动。如果你想换加油站,车就废了。
- 结构混乱(四个仓库): 他们的代码被拆散在四个不同的“房间”(仓库)里。维护人员想要修一个螺丝,得跑四个房间找图纸,非常累人。
- 每次启动都要“现买零件”: 每次流水线运行,它都要临时去网上下载和安装所需的工具(就像每次做饭前,厨师都要先去菜市场买菜、洗菜、切菜,而不是提前准备好)。这导致每次运行都要等很久(平均 724 秒),而且如果网络不好,菜买不到,饭就做不成了。
- 脆弱且不安全: 因为太复杂,稍微改一点东西,整个系统就可能崩溃。而且因为临时下载东西,很难保证每次用的“食材”都是干净安全的。
2. 解决方案:把厨房搬进“集装箱”
为了解决这些问题,Bankdata 的团队决定进行一场**“大搬家”。他们把流水线从 Jenkins 搬到了GitHub Actions**(另一种更现代的自动化平台),并采用了**“容器化”**技术。
我们可以用**“移动厨房”**的比喻来理解这次迁移:
抽象层(Abstraction Layer)= 通用翻译官:
以前,厨师(代码)只会说"Jenkins 方言”。现在,他们请了一位翻译官(抽象层)。厨师只需要对翻译官说“我要炒菜”,翻译官负责把这句话转换成 Jenkins 或 GitHub 都能听懂的指令。这样,以后想换平台,只需要换翻译官,厨师不用重新学语言。
容器化(Containerization)= 预制菜与移动厨房:
以前,每次做饭都要临时找锅碗瓢盆。现在,他们造了一个**“移动集装箱厨房”。这个集装箱里预先装好了**所有的锅碗瓢盆、调料、甚至厨师需要的工具(COBOL 编译器、测试工具等)。
- 好处: 无论这个集装箱被运到哪里(任何服务器),里面的环境都是一模一样的。厨师不需要再临时找东西,直接开火就能做。
精简仓库 = 整理杂物间:
他们把分散在四个房间的图纸,全部整理进了一个整洁的文件夹里。现在,谁想改代码,一眼就能找到,不再迷路。
3. 成果:从“老牛拉车”到“高铁飞驰”
这次改造的效果非常惊人:
- 速度提升 82%: 以前跑一次流水线要12 分钟(724 秒),现在只需要2 分钟(130 秒)。就像把老牛拉车换成了高铁。
- 更稳定、更安全: 因为所有工具都预先打包在“集装箱”里,不再临时下载,所以环境永远一致,不会出现“今天能跑,明天就报错”的情况。同时,因为工具是预先审核过的,安全性也大大提高了。
- 不再被“绑架”: 现在,这个流水线不再死死绑定在 Jenkins 上。如果未来 Bankdata 想换到别的平台,只需要调整一下“翻译官”,核心逻辑完全不用动。
4. 学到的教训(给其他老企业的建议)
这篇文章最后总结了一些宝贵的经验,就像给其他想改造的老企业开的“药方”:
- 不要直接改老代码,要加个“中间层”: 就像给老房子加电梯,不要拆掉承重墙,而是加一个独立的电梯井(抽象层),这样以后换电梯品牌也不影响房子结构。
- 提前准备好所有工具(容器化): 别指望每次开工都临时找工具,把工具箱打包好,随叫随到。
- 别忘了“人”的因素: 技术再好,如果老员工(COBOL 程序员)觉得新系统太难用,他们也会抵触。所以,要让他们参与进来,甚至提供像 VS Code 插件这样的工具,让他们在熟悉的界面里工作,减少不适感。
- 安全不仅仅是“藏好密码”: 在日志里把密码藏起来是不够的,要从根本上防止密码泄露,比如严格控制谁能访问什么。
总结
这篇论文讲述了一个**“老树发新芽”的故事。Bankdata 没有抛弃他们赖以生存的古老 COBOL 系统,而是通过“容器化”和“抽象层”这两项现代技术,给这些老系统装上了现代化的“自动驾驶系统”**。
结果就是:跑得更快了(效率提升),更安全了(风险降低),而且以后想换车(换平台)也更容易了。 这对于任何拥有古老但关键系统的企业来说,都是一个极具参考价值的成功案例。
论文技术总结:COBOL 的便携式与安全 CI/CD——来自工业迁移的教训
1. 研究背景与问题 (Problem)
背景:
Bankdata 是丹麦银行的合作 IT 服务提供商,其核心系统基于运行在 IBM 大型机上的遗留 COBOL 应用程序。在受监管的金融行业,CI/CD(持续集成/持续交付)流水线对于确保系统稳定性、合规性和安全性至关重要。
核心问题:
原有的 Jenkins 基于 Groovy 脚本的 COBOL CI/CD 流水线存在严重的技术债务,具体表现为:
- 架构脆弱且耦合度高: 流水线逻辑分散在四个相互依赖的仓库中(模板、Worker、工具、配置),且深度耦合于 Jenkins 特定的 API 和函数(如
container, withEnv, currentBuild 等)。
- 运行时依赖管理低效: 关键依赖(如 COBOL Expander)在流水线运行时动态安装,导致环境不一致、执行时间长且维护成本高。
- 供应商锁定 (Vendor Lock-in): 过度依赖 Jenkins 使得迁移到其他 CI/CD 平台极其困难,限制了组织的灵活性。
- 安全与合规风险: 运行时安装依赖和复杂的配置增加了安全漏洞的风险,且难以满足金融行业严格的审计要求。
- 性能瓶颈: 流水线执行缓慢,平均运行时间长达 724 秒,严重拖慢了开发反馈循环。
2. 方法论与迁移策略 (Methodology)
研究团队将流水线从 Jenkins 迁移至 GitHub Actions,并采用了容器化架构和抽象层设计。主要策略包括:
A. 解耦与抽象层 (Decoupling & Abstraction)
- 平台逻辑抽象: 识别并提取所有 Jenkins 特定的函数(如环境管理、状态报告、文件操作),将其封装在一个独立的 Groovy 包中。
- 翻译层 (Translation Layer): 创建一个中间层,将流水线核心逻辑与底层 CI/CD 平台(Jenkins 或 GitHub Actions)隔离。核心逻辑仅调用抽象层函数,而非直接调用平台 API。
- 重构环境管理:
- 移除对 Jenkins
currentBuild 对象的依赖,改用环境变量或 Git 命令获取元数据。
- 用标准 Groovy 的
println 和 try-catch 替换 Jenkins 特定的 echo、error、catchError 等状态报告函数。
- 将 Shell 脚本执行封装为通用的 Groovy 函数(使用
ProcessBuilder),并自定义凭据处理逻辑以替代 withCredentials。
B. 容器化与依赖优化 (Containerization)
- 预构建 OCI 镜像: 创建一个包含所有必要工具(Groovy, GnuCOBOL, COBOL Expander, COBOL Check, Zowe CLI, Node.js 等)的预构建容器镜像。
- 消除运行时安装: 所有依赖在镜像构建阶段安装,流水线运行时直接复用,消除了动态安装带来的延迟和不一致性。
- 镜像瘦身: 通过一系列优化步骤(如从 Debian 切换到 Alpine 基础镜像、移除构建依赖、清理缓存、使用特定版本的 JDK 等),将镜像大小从 1.4 GiB 减少至 559 MiB(减少 60%)。
C. 仓库结构简化
- 将原本分散在四个仓库的逻辑合并为一个统一的仓库,简化了依赖管理和代码导航。
- 利用 GitHub Actions 的机制(如 CODEOWNERS、预接收钩子)强制执行应用代码与流水线逻辑的分离。
3. 关键贡献 (Key Contributions)
- 受监管环境下的迁移蓝图: 提供了一份在严格合规要求(金融、大型机)下,将遗留 CI/CD 流水线从 Jenkins 迁移到现代容器化架构的详细端到端方案。
- 平台无关的抽象模式: 验证了通过抽象层隔离平台特定逻辑的有效性,使得核心流水线逻辑可以在不同 CI/CD 平台(Jenkins, GitHub Actions)间无缝迁移,显著降低了供应商锁定风险。
- 遗留系统的现代化实践: 展示了如何在保留 COBOL 核心业务逻辑不变的前提下,通过容器化和 DevOps 实践提升大型机生态系统的可维护性和性能。
- 技术与组织的双重评估: 不仅提供了量化的性能数据,还结合利益相关者的定性反馈,探讨了技术迁移中的组织文化、开发者体验和安全性挑战。
4. 实验结果 (Results)
定量指标
- 执行时间大幅降低: 流水线平均运行时间从 724 秒 降至 130 秒,减少了 82.1%。
- 镜像体积优化: 容器镜像大小减少了 60%(1.4 GiB -> 559 MiB),显著提升了构建速度和传输效率。
- 稳定性提升: 通过预构建镜像消除了运行时依赖安装的不确定性,执行环境更加可复现。
定性反馈
- 可维护性: 代码库结构简化,单一仓库降低了认知负荷,新成员上手更容易。
- 安全性: 依赖项被预审查并固化在镜像中,配合更严格的密钥管理策略,提升了整体安全态势。
- 用户体验挑战: 开发者反馈 GitHub Actions 的界面在步骤级可视性上不如 Jenkins 细致,且部分 COBOL 开发者对 Web 界面感到不适应(建议通过 VS Code 插件缓解)。
- 技术栈选择: 继续使用 Groovy 而非 YAML 编写流水线逻辑,虽然增加了学习门槛,但保证了跨平台逻辑的连续性和独立性。
5. 意义与启示 (Significance)
- 行业示范效应: 证明了即使是高度受监管、依赖数十年历史遗留技术(COBOL/大型机)的金融机构,也能成功实施现代化的 CI/CD 流程,而无需牺牲合规性或系统稳定性。
- 通用架构原则: 提出的“抽象层 + 容器化”模式不仅适用于 COBOL,也适用于其他存在紧密耦合和运行时依赖安装问题的遗留系统或现代技术栈。
- DevOps 文化融合: 强调了在技术迁移过程中,必须尽早让遗留系统开发团队(COBOL 开发者)参与,平衡架构的纯粹性与实际可用性,以确保变革的顺利落地。
- 安全与速度的平衡: 展示了通过预构建和依赖固化,可以在提升构建速度的同时,增强供应链安全和审计能力,打破了“安全即慢”的刻板印象。
局限性:
研究主要验证了在 GitHub Actions 上的表现,未能在多个 CI/CD 平台进行广泛的通用性测试;且由于组织政策限制,连续部署(CD)场景未在真实生产环境中验证。
总结:
该论文通过 Bankdata 的实际案例,成功展示了一种将脆弱、慢速且高度耦合的 Jenkins COBOL 流水线转化为快速、安全且平台无关的容器化架构的方法。其核心在于抽象层设计和容器化依赖管理,为同类工业场景的现代化改造提供了宝贵的经验和可复用的蓝图。
每周获取最佳 computer science 论文。
受到斯坦福、剑桥和法国科学院研究人员的信赖。
请查收邮箱确认订阅。
出了点问题,再试一次?
无垃圾邮件,随时退订。