本文要点
- 大型机程序开发人员不仅正在退休,而且正在过时。年轻一代的开发人员对大型机职业生涯兴趣索然。
- 大型机程序开发人员曾被比成是公共汽车驾驶员,他们唯一的工作就是让大量的数据持续移动。
- 大型机并非老化了。如果与 Microsoft 和 Linux 在性能、扩展性、安全和可靠性上做对比,大型机完胜。
- 代码重构为可复用模块的过程中,应使用测试,并采纳敏捷实践。大型机应用的现代化并不能体现为月度财报中的投资回报率。
我们经常使用 Uber、浏览 Pinterest、发送推文并更新 Facebook。我们每天都会听说一些人快速成为百万富翁,看到亿万富翁的数量在不断增长,他们不断地在我们现在的高科技世界中推出一些最新玩意。但是我们忽视了一点,所有业务的近乎 70% 是在大型机上处理的。那些年轻网红匆忙拼凑起来的玩意,充斥了我们所见所闻的世界。但事实上,我们所坐的椅子、所支付的账单、所使用的健康医疗,都是由大型机所管理的数据提供的。的确,80% 以上的制造业、银行业和健康医疗行业是运行在大型机上的。
我们能听到大量关于新市场货币化的宣传,但却没有认识到大型机代码的重要性。当然,这里存在一些问题……很多大型机开发人员是接近或已经过了退休年龄的爷爷级人物。现实中更严酷的一面是,他们不仅正在退休,而且正在过时。(让我们为去年去世的 Jim Stanicki 和 John Stalher 做一个短祈祷,他们是两位典型的大型机开发人员,也是我的朋友。)
代码重写
我们是否应该重写旧的大型机应用?这不容易实现。当然我知道,大家已对代码重写耳熟能详了。不少并非大型机应用的 Visual Basic、dBase III 和 PHP 程序会每隔五年就重写一次,原因在于它们的代码写得并不是很好。而与此同时,我们看到大型机应用已经良好运行数十年了。重写大型机应用的 ROI(投资回报,Return On Investment)并非在于此。举个例子,我在上世纪八十年代中期为 Hanover Brands 有限公司编写了的流量系统目前依然在使用。
但是现在我们面对着退休和过时的问题。那么我们为什么不能硬着头皮去做重写?
重写从来就不是一件容易的事情。对于大型应用,重写常常会失败。就在数个月前,我为 Ruby and Rails 重写了一个小小的简单 PHP 应用程序。尽管我精通 Ruby 并熟悉 PHP,并且这一程序只有一千行多点,但我还是丢失了一些内容。大型机的 COBOL 和 RPG 应用则略为复杂。使用 RPG 编写的程序,一万多行是很常见的;而如果使用 COBOL 编写,动辄具有两万多行。如果代码需要在上百个程序中复制,那么一个应用就会有上百万行的代码。更糟糕的是,其中不少程序是在模块化编程技术出现之前编写的。因此,在这样庞大代码中的所有变量是全局的。记得在数十年前,我曾在文章和研讨会中十分关注这一问题,我们像第欧根尼(译者注:Diogenes,古希腊哲学家,犬儒学派的代表人物。他所做的一件事情是,每天白天打着灯笼在街上“寻找诚实的人”)那样在大型机代码中寻找局部变量。第欧根尼从未发现诚实的人,在 70 年代前后的代码中寻找变量中也存在着同样的问题。
RPG 程序本身就是非常难以阅读和理解的。多年来,RPG 语言一直只能用六个字符表示变量名。事实上事情更糟,RPG 语言存在一些软件缺陷。如果我们在两个不同的表中使用了同一列名,那么它们将共享同一内存空间。因此为了识别变量所关联的系统表,RPG 程序人员需要使用二到四个如此珍贵的六字符列名。该软件缺陷在二十年前才被修复,现在它的变量和数据库列名长度支持 32 个字符。但是在 RPG 程序中,六字符变量名依然占据主流。
在 1992 年前后,此时我是 Circuit City 编程团队中的一员。当时我就 COBOL 模块化技术为团队做了一次演讲。演讲后,团队中一位最优秀的 COBOL 编程人员指出,她并未看到 COBOL 模块化的好处。
大家知道,在讨论一个函数是否应该超过 6 或 9 行的问题上,我可以与其他 Ruby 开发者争得头破血流。在 Ruby 开发中,如果你肆意使用全局变量,完全可能会被解雇。所以当我回想起这些一万到两万行的程序时,不禁哑然失笑。维护使用 Cobol 和 RPGb 编写的庞大代码,这往往比巫术更诡异。如果要尝试做一些直觉上可以工作的更改,我们要点上香并撒上圣水,向各方神灵祈祷这一更改会奏效。
Cobol 和 RPG 的主流开发实践中充斥着过时的语法。我们谈论的是丑陋的代码。在一个程序中经常会有数千行代码被注释掉,还有许多部分是完全没有使用的。查看这样的代码就像走进一个有囤积癖好的人的房屋,其中充斥着无用的垃圾。更过分的比喻是,垃圾堆越多,就越容易腐烂,并且会发出恶臭,正如我们所讨论的代码味道。事情是,我们每天都会用到的流程和数据都会流经这个腐朽的旧代码,而它的维护人员正在退休和过时。
敏捷
老实说…我从这一职业生涯中跳出来的原因在于大型机开发的速度,或者说缺乏速度。RPG 和 Cobol 的开发实践和工具集已经衰落。诸如测试驱动开发、源代码控制、现代编辑、代码重构、敏捷等理念,多年来我一直致力于将它们转化为文字,并付诸文章和研讨会中。但是在 RPG 和 Cobol 开发项目中,我不仅需要忽视其中大部分理念,而且几乎找不到可以使用这些理念的项目。
对于上一段话,我重点说一下其中的敏捷性问题。大型机应用程序开发实践缺乏敏捷性,因此很难以适应市场需求。通常,考虑到此类旧应用程序的失败,以及它们的支持人员即将退休,C 级别高管(译者注:指具有 CTO、CEO、CFO 等头衔的企业高管)会建议采购昂贵的 ERP 系统,或是完全重写。我们都听说过这样项目的相关恐怖经历。
现代机器
我们应了解,大型机并非过时的。它们并非 System 360 和 AS/400 这样的昨日黄花,而是 IBM z/OS 和 IBM i 这样的 64 位操作系统,具备 Linux 和 Windows 所无法企及的可靠性和可扩展性。它们对于复杂数据中心而言,自建的整体成本也较低。我们可以横向扩展大型机,而非纵向扩展。 在大型机上也可以运行最新的软件。例如,我们可以在一台主机上运行数千个 Docker 镜像。运行在 i 系列机器上的 DB2 数据库,可以说是这个星球上最好的数据库。至于热门技术,几年前,我在一个团队中实现了将 Ruby and Rails 移植到本地 IBM i 操作系统上。银行应用程序是在大型机上运行的,这主要出于安全上的考虑。正是银行家资助了 Rails 迁移到 IBM i 平台。大型机具有巨大的优势,涉及从巨大的横向增长到最终的安全性、近乎 100%的可靠性。当然,尽管事实上 IBM 销售大型机的数量在减少,但现有机器提供了很好的升级和扩展,因为它们具有天文学量级的水平可扩展性。
老化的并非机器,而是大型机的应用程序和程序开发人员。
事情是否已经搞砸了?
我们曾担心千年虫会让大型机崩溃,事实上它并没有。一起都很好。这是因为管理层最终开始认真对待从两位数转到四位数的问题。如果管理层能认真对待关键技能的损失这一问题,一切都会好起来的。
下面在详解介绍具体细节前,让我概括一下我给出的解决大型机编程人员退休和过期问题的方案:
- 数据库的现代化;
- 应用代码的重构;
- 培训现有大型机开发人员的敏捷,并薪火相传;
- 挑选优秀者成为大型机开发人员;
- 将已有代码转换为 API。
数据库的现代化
第一步是数据库的现代化。隐藏在这些二十至四十年前的应用程序之后的,是保存在世界上最好的数据库和操作系统中的大量数据。许多大型机数据库的创建,要先于今天众所周知的数据库规范化和优化技术的创立。就在十年前,我还是要把 Web 前端置于明显之处,放在一张牌桌上。一些工具和可用技术可以让我们继续运行遗留应用,无需修改旧的数据库模式结构。根据我的经验,重构数据库并非难事。
应用代码的重构
我早些时候对大型机代码现状表示出了强烈的不满。现在我知道,大型机代码可以被重构到更为敏捷的程度。我并不是要探讨重构本身。重构是一种在不改变代码行为的情况下重新构造代码的过程,因此 C 级别高管不应该担心大规模重写可能会导致停机的问题。
重构的第一步是将代码置于源代码控制下。我强烈推荐使用 git。或许你的大型机代码已经使用源代码管理包管理,但是我对大型机源代码管理包的经验是,它们助长缓慢的开发,并阻碍常见的重构策略。只要代码置于 git 管理之下,那么我们可以删除掉注释的代码,因为保留旧版本的代码是源代码管理的工作。
重构的第二步是更新开发环境。虽然功能强大的 IDE 出现了二十多年,许多大型机开发人员仍然使用字符编辑器。这些现代 IDE 是与重构工具一起绑定使用的。
第三步是建立单元测试策略。 单元测试通常会对程序行为做出非常具体和详细的测试。这是我们没有时间去做的事情。我建议遵循由 Llewellyn Falco ( http://llewellynfalco.blogspot.com/ ) 提出的“批准测试”(Approvals Testing)策略。审批测试的基本理念是分别做执行例程之前和之后的状态快照。该快照可以是任何内容,从数据库的查询结果到 PDF、CSV 格式的文档。发挥你的创意吧!在存储了快照后,我们就可以修改例程,并使用之前和之后的映像去验证重构并没有改变行为。虽然在调用大型机例程时,最终可能会使用使用到 Java、Ruby 或 Python 的测试基础结构,但此类操作并不复杂。
如果构建了单元测试策略,重构应该最先实现变量名称可读和易于理解。然后再开始进入模块化的过程中,尽量减少使用全局变量。在大型机代码中,重复代码泛滥,所以我们需要借助于工具去查找重复代码,然后对它们创建一些通用模块。
授权现有开发人员
重构策略的关键是在于最好的大型机开发人员。忠言逆耳,但是大型机开发人员已被他们的雇主看成是巴士司机的角色。管理层认为开发人员的工作就是在各点间移动数据。一旦这一过程发生中断,开发人员就需要去修理引擎,直到他们能够回到大巴上并继续移动数据。从我个人的经验看,他们往往不受重视并且报酬过低。其中不少大型机开发人员没有学位,并且相对于 C 级别高管和常青藤联盟 MBA 学员,他们似乎并不具备考虑下个季度投资回报率的能力。
我们应授权这些大型机开发人员。就敏捷开发实践对他们进行培训,并且他们自己也要成为培训师。他们需要在重构和其后的模块化 API 创建上得到帮助。我们还应考虑到退休和过时的问题,因此管理新开发人员的培训应是授权大型机开发人员的一部分。
如果在现有的主机开发人员中,没有人能站出来成为项目主管,那么我们就应该从外面招聘一名。问题在于,虽然有许多人具备推进此工作的能力,但他们可能已经转向了管理或培训,或是像我一样转向了其它的编程语言和平台。与这些人相关的一个问题是,他们在几十年前就厌倦了走马灯式(Revolving door)的 C 级别高管,这些高管拒绝了大型机开发现代化的建议。许多这些前主机开发人员可能只是会建议去购买 ERP,给 Oracle 打电话,或者完全重写,尽管就他们的经验来看这可能会是失败。所以准备好轮流与这些人打交道。
那么在哪里可以找到这些曾经的大型机开发人员?我们可以在 LinkedIn 上搜索具有良好沟通技能、新技术和敏捷上的经验并试图隐藏大型机经历的人,也可以参加 Java、Ruby、JavaScript 等会议并与 50 岁以上的开发人员交谈。从他们的年龄看,他们可能曾经是大型机开发人员,并熟悉新技术,最重要的是敏捷开发。
如果读者知道自己在找什么样的人,那么我们可能不需要介绍得过多。本段内容可能会被裁掉,因为本文编辑曾是一名大型机开发人员,也是一位敏捷教练。他可能会裁掉本段内容,因为他几年前就辞去了“大巴司机”的工作,并找到了一个类似于他的人去管理大型机现代化项目。[编者按:不,我并未裁掉本段,因为我同意作者的说法。]
挑选优秀者成为大型机开发人员
大学并不会教 Cobol 和 RPG。在一些关注“技能消亡”问题的博客帖子和文章中,建议大学应增加添加大型机的课程,吸引千禧一代从事大型机职业。
我不认为吸引千禧一代是一种解决方案。我不会建议任何年轻人在大型机上发展自己的职业生涯。这一行业就业机会少得多,发展速度也缓慢,职业生涯不会太顺利。我的建议是:一、对现有的非 IT 人员再培训;二、强制三四十岁的人进入大型机行业。这两个建议听起来都很疯狂,但是对于愿意在大型机上开始其职业生涯的年轻 IT 毕业生,我对他们的能力心存质疑。
比当今风行的的多态、多平台的程序开发人员,成为一名大型机开发人员所需的技术知识更专一。公司需要的不是具有 NodeJS 和函数式编程技能的人,而是具有商业头脑的人,他们渴望学习,而且非常简单和聪明。有很多非 IT 专业的聪明人,他们正经历职业中期焦虑,在经过一年的职业训练后会有机会薪酬翻倍。一个值得挖掘的领域是退休人员。
将代码转换为 API
将重构的代码转换为 API,是大型机现代化过程的最后一步。这些应用将成为可重用的软件组件。通常,大型机代码的参数列表非常复杂,创建 API 似乎是不可能的事情。鉴于此,我们要创建一个或多个包装程序,这可以使用 Cobol 或 RPG 编写,也可以选择新语言编写。我喜欢使用的技术是创建包装传统模块的 SQL 存储过程。使用 SQL 存储过程时,任何具有 SQL 接口(例如 JDBC,ODBC 驱动程序或其它)的人都可以使用这些例程。
使用通过 API(例如 SOAP,REST 或其它)提供的遗留代码,并使用面向所有的单元测试,可以做到完全敏捷的开发。可以选择任何语言编写新的代码,当然这些工作可以雇用千禧一代完成。
一些更为敏感和复杂的程序,它们可能在客户流失报告中位列前茅,现在已经可以转换为新语言编写。
大型机的敏捷
尽管大型机应用程序在过去的半个世纪内都是非常的可靠,但它们几乎没有做任何自动化测试。而大型机从业者或者是不了解重构策略,或者在启动重构问题上没有得到 C 级别高管的支持。总而言之,代码已经不适应不断变化的业务需求。现有的大型机开发人员正在以惊人的速度退休,劳动力也没有得到补充。
摆脱大型机远非最理想的解决方案。重写或转换为 ERP 的实现代价昂贵,并且充满风险。但是大型机本身没有老化。事实上,它们在性能、弹性、安全性和可靠性等方面完全超越 Microsoft 和 Linux。并非是机器在老化,而是应用程序和程序员正在老化。
我们要做的是实现数据库的现代化、代码的重构、成为敏捷并加强对编程人员的内部培训。最后在大型机展现出优势之处,开始将新模块化的代码转换成新语言编写。
问题在于,上述解决方案都取决于 C 级别高管的采纳。高管在采纳之前,需要审视季度业绩,并考虑未来两到五年内,如果失去这些被低估的大型机开发人员会有什么样的后果。
本文作者
Don Denoncourt 是 simplethread.com 的一名开发人员。在 Windows 和 Linux 时代开始前,他就一直在编码,更不用说互联网时代了。在九十年代初,Don 从 RPG 和 Cobol 开发转向 C 和 C++ 开发。在 1996 年,他先于 Java 发布使用了 Java。在以自己的方式使用 Java 框架扩展(包括 Struts,Spring 和 EJB)编写代码后,他开始使用 Ruby and Rails 的 Convention-over-Configuration 框架。在 2011 年最终定格在 Rails 开发之前,Don 做了 Groovy 和 Grails 开发。Don 喜欢写作,并且出版了多本书和数百篇技术文章。自上个世纪以来,Don 一直在国内工作。在工作闲暇之余,Don 喜欢和三个孙子在一起。为了让自己的思想保持年轻,Don 用意大利语阅读和聆听小说。并且为了使自己的身体保持年轻,他也是一名狂热的越野爱好者和街头骑士。
评论