速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

银行祖传系统重构实例:创立 12 年,只支持 Python 2,跑着 500 多个应用程序

  • 2020-08-20
  • 本文字数:3232 字

    阅读完需:约 11 分钟

银行祖传系统重构实例:创立12年,只支持Python 2,跑着500多个应用程序

提到遗留系统,你会想到什么?


  • 还在使用 Java 5 的路过

  • JDK 1.6 的我不说啥了

  • 很多坑

  • 难维护

  • 从零开始(重写)

  • 盼着 IE 什么时候不再能使用

遗留系统

对于遗留系统,程序员们并不陌生。据维基百科介绍,遗留系统是一种旧的方法、旧的技术、旧的计算机系统或应用程序。


张逸认为,遗留系统首先是一个还在运行和使用,但已步入软件生命周期衰老期的软件系统。它符合所谓的“奶牛规则”:奶牛逐渐衰老,最终无奶可挤,然而与此同时,饲养成本却在上升。这意味着遗留系统会逐渐随着时间的推移,维护成本会不断地增加。


在《从300万行到50万行代码,遗留系统的微服务改造》一文中,技术琐话阐述了遗留系统的一些共同特征。


  • 庞大的单体应用:遗留系统大多是多年积累下来的“巨无霸”系统,以单体应用形式呈现。

  • 难于修改:多年的代码累积过程中疏于重构,导致代码的可读性和可扩展性较差。

  • 维护成本很高:在庞大的代码中寻找 bug 的根本原因可能会比较困难。此外,运维也是难题,比如在本章开头提到的 Perl 系统,没有 APM 工具支持它的监控。

  • 学习成本高昂:由于设计陈旧或技术过时,可能了解遗留系统技术和业务的人已经很难找到。

  • 缺乏质量保障:由于过去缺少投入,许多功能基本上没有自动化测试来保障质量。


事实上,在传统企业甚至互联网企业往往存在大量的遗留系统。这些遗留系统大多都能正常工作,有的可能还运行着关键业务或者持有核心数据。但是,大部分遗留系统通常经常存在技术陈旧、代码复杂、难以修改等特点。


我们看到,有的遗留系统给企业带来不可挽回的损失:


系统出现故障,当年负责编写这个程序的开发者却在 15 年前去世,现在已经无人能看懂他的代码,结果一个 bug 导致千万损失。——《程序开发者去世,代码没人懂,一个bug导致千万损失》。


还有的遗留系统在企业技术变革中慢慢淡出:


笔者曾经维护过一个 Perl 实现的网站,在 2015 年被解耦前,它已经工作了十几年,为公司占领市场立下了汗马功劳。奈何技术陈旧,维护困难,最后在微服务化过程中慢慢淡出。——《从300万行到50万行代码,遗留系统的微服务改造


当然,也有遗留系统至今活得很好,默默贡献自己的力量。

印象深刻的遗留系统

我在一家银行工作时,遇到了一套令人印象深刻的遗留系统。


它最初创建于 2008 年(北京奥运会那一年),花费数周时间进行开发。整套系统具有完整的 CI、CD、单元测试、代码审查、自动部署等功能。自创建以来,大部分时间,它的核心基本保持不变,但是外围有许多改进(代码审查、日志记录、性能、身份验证等)。


从某种方面说,它相当于是公司内部的 AWS lambda 等效系统。


你可以编写一个 Python 脚本(Python 是该系统唯一支持的语言),大约 5 分钟内就能审核完毕并投入生产,准备供世界使用。


这个系统并不是官方层面的“战略”解决方案,它不为人知,也没有做过广告宣传。但是,它被频繁用于多个业务部门,并且不时有新的发展。因为它太好用了,所以大家都没法抛弃它。


我们部门有个暑期实习生,他利用这个系统,只花了 3-4 周就基本完成了他们的小项目(实习期应该有 2-3 个月)。而同时,其他实习生群体还没有弄清楚如何在“战略”框架内交付应用程序。


我最后一次统计时,那里运行着 500 多个应用程序。值得注意的是,生产日志显示,其中 80%处于活跃状态。


外科手术式维护

不过,在不断变化的软件世界中,所有美好的事物都必须迎来终结。到头来, 这套系统还是要重新设计或被抛弃,原因如下:


  • Python 2.7 即将寿终正寝

  • 身份验证库已经弃用

  • 中间件有很长时间没有重新编译或升级了

  • 有一些潜在的 UI 改进需要完成


为了拥抱变化,这个系统开始升级。而在升级到第一批生产脚本时,我们就遇到问题。


有两个用户每隔 1 小时就报告一次问题,我们研究问题后发现其仅限于 IE 浏览器。在 IE 浏览器中,某些功能无法正常运行。


实际上,这家银行很早前就弃用了 IE,转而支持 Chrome 浏览器。全公司 25 万的员工被要求禁止使用 IE 浏览器。如果尝试在 IE 中打开某些站点会报错,会提示你改用 Chrome。这对用户导航有副作用,因为所有内容都是相互连接的(想象一下 report.example.com 链接到 otherreport.example.com 并调用 internalapi.example.com,可是某些 URL 是被阻止的)。


好消息是,最近的升级并没有倒退回去,而是简单解决了这个问题。IE 被屏蔽,并向 5000 位开发人员发出了通知:不再支持 IE 浏览器。问题解决了。


供参考:最好硬屏蔽 IE 以改善用户体验,IE 用户习惯了在其他浏览器中重试。也许最近几年开发的内部应用中有三分之一无法在 Chrome 之外运行,不是页面空白,要么就是到处都有损坏的小部件。


于是,升级按计划进行。在最后,我们遇到一个小麻烦:一个独立的脚本停止工作了 。


该脚本最初创建于十多年前,也就是这个框架刚创建后的几个月内。这是最早发布的应用程序之一,也许从历史上来看是第 8 个(现在有 500 多个)。


它实际上不是代码,而是某种模板。众所皆知, 该框架带有自己的模板语言和例程 (二十一世纪的开发人员应注意:请使用 jinja 进行模板化)。已经没有东西还在用这个模板功能了。团队进行了一些调整,然后系统又恢复了正常工作。


最终,升级完成。


新版同时支持 Python 2.7 和 Python 3.7,支持 OpenID Connect 和 Kerberos,在各处添加了一些消息和错误以简化使用,还更新了开发文档等等……


经过 12 年的可靠和忠诚的服务,这款旧系统并没有被弃用。恰恰相反。它还在兢兢业业做事,并且肯定还会再活起码 12 年,比现在所有的 JavaScript 和战略框架寿命都更长。


唯一的缺点是 lambda 请求的启动时间较长(基线为 5 秒)。它适合处理偶尔访问的报告和 API,不适合用于高性能 API 或缓存,后面的情况下最好使用其他技术,推荐 tornado 用作 Web 服务器 Web 框架。

看遗留系统的“正确姿势”

在《关于遗留系统,看看Google怎么办》一文中,Cheng 哥总结了几点,个人觉得挺好,分享给读者。

1. 保守态度,不轻易改变

老的系统,面对的场景没有发生太大变化,原来什么模式就是什么模式,不要为了改变而改变,比如运营商的 CT 系统、银行的核心交易系统等关乎国计民生。


同时,因业务特性的原因,本身不会有很频繁、很大的变更,这种时候,现有手段,慢一点、稳妥一点,哪怕流程繁琐一点都没问题。如果改,就可能会带来极大的风险,也不会带来太大收益,不改,也能维护下去,孰优孰劣,自然就清楚了。


现在,运维有一种提法,叫做双态运维,就是针对系统特点,分为稳态和敏态,不同场景采用不同的模式。

2. 重构过渡

如果业务场景变化了,要求系统必须能跟上节奏,这种情况下,建议通过重构,且逐步迁移的方式过渡。也就是,根据新的场景,设计适应的技术架构,能够满足效率、稳定和成本的要求,然后老系统上的业务和流量逐步迁移过去。


如果是直接在承载业务运行的老系统上改,成本和风险会非常高,实际情况下是不可行的。

3. 从现在开始,重视标准统一

前面提到传统行业的软件体系,大多是多厂商建设,标准不统一。但不管是做 DevOps,还是 SRE,甚至最基础的自动化,标准都是前提中的前提。所以,如果当前正在规划新的技术体系,或者有针对某些遗留系统重构的机会,从一开始规划好各种标准体系,就非常重要,建设前没有标准,事后再去统一标准,基本就没有机会了。


互联网的技术体系,从最早期的单体架构,没有标准,到系统拆分的服务化演进,形成统一标准,再到基于统一标准的运维自动化、持续交付以及稳定性建设,最终形成大中台的体系,也是遵从着这样一个过程和规律走下来。


只不过,互联网公司在早期没有太大的业务和技术的包袱,所以可以小步(甚至大步)快跑,大胆试错,快速迭代,整个过程的进展会更快一些,但是规律是一样的。不过,当规模到了一定体量,所面对的问题,跟传统行业也是一样的,一样会有遗留系统。既不可能随意放弃(还在承载业务),也不可能说重构就重构,成本和代价是必须要考虑的。


对遗留系统,你有什么看法?欢迎留言告诉我们。


参考资料:


https://thehftguy.com/2020/07/09/the-most-remarkable-legacy-system-i-have-seen/


2020-08-20 15:023420
用户头像
王强 技术是文明进步的力量

发布了 835 篇内容, 共 443.1 次阅读, 收获喜欢 1753 次。

关注

评论

发布
暂无评论
发现更多内容

InfoQ 极客传媒 15 周年庆征文|在Flutter中自定义应用程序内键盘

坚果

InfoQ极客传媒15周年庆

5年“研究”3年“实战” 之后的满分答卷

青藤云安全

网络安全 容器安全 安全服务 云原生安全

SphereEx 正式开源面向 Database Mesh 的解决方案 Pisanix

SphereEx

开源 SphereEx 云上数据库 Database Mesh Pisanix

华为云零代码开发图片压缩工具

乌龟哥哥

6月月更

从 0 到 1,探究百亿流量验证下的 MVVM 框架设计

图灵教育

百度 MVVM 全栈设计

中原银行统一日志平台

中原银行

海量数据 中原银行 日志平台

谁说Redis不能存大key

华为云开发者联盟

数据库 华为云

君可归烈士寻亲系统开发实战

乌龟哥哥

6月月更

跟我学Python图像处理丨5种图像阈值化处理及算法对比

华为云开发者联盟

Python 人工智能 华为云

尽一份孝心,为家人做一个老人防摔报警系统

华为云开发者联盟

IoT 华为云 防摔倒报警系统

干货合集│最好用的 python 库都在这

Python 有趣的技术知识 6月月更

身为程序猿——谷歌浏览器的这些骚操作你真的会吗

孤寒者

6月月更 浏览器操作 小技巧 程序猿必会

八连冠!浪潮云连续8年蝉联中国政务云市场第一位

云计算

大数据生态安全框架的实现原理与最佳实践(上篇)

明哥的IT随笔

大数据 hadoop hive 数据安全

入驻快讯|欢迎XCHARGE智充科技正式入驻 InfoQ 写作社区!

Geek_60c26d

在线沙龙 | 开源小秀场——数据库技术应用实践

SelectDB

数据库 技术分享 apache doris 沙龙

【MySQL字符串数据类型优化】char和varchar的区别

写代码两年半

数据库 sql 6月月更

什么是集群?为什么要使用集群架构?

Finovy Cloud

集群架构 云渲染 GPU服务器

flutter系列之:Material主题的基础-MaterialApp

程序那些事

flutter 程序那些事 6月月更 widget

跨平台多媒体渲染引擎OPR简介

阿里巴巴文娱技术

音视频 弹幕 渲染

快来极狐GitLab SaaS 学习全球顶级的开源项目吧

极狐GitLab

开源

秒云云原生信创全兼容解决方案,推动信创产业加速落地

MIAOYUN

云原生 信创 信创云

音频 3A 处理实践,让你的应用更「动听」

融云 RongCloud

智充推出NET ZERO SERIES储能充一体机,携手比亚迪共创净零未来

Geek_60c26d

一、Kafka安装

星期35

小程序启动性能优化实践

百度Geek说

直播预告 | 在阿里云 ESSD 云盘上部署 PolarDB for PostgreSQL 集群

阿里云数据库开源

数据库 postgresql 阿里云 开源

CREMB Pro 后台子管理员 403 问题分析

CRMEB

InfoQ 极客传媒 15 周年庆征文|手把手教你使用Python实现一键抠图,照片换背景|so easy!

迷彩

Python AI 前端 6月月更 InfoQ极客传媒15周年庆

亚马逊云科技向你发出召唤——游戏开发者,集合!

亚马逊云科技 (Amazon Web Services)

react.js edge postcss

充电桩的B面是......不只公众号?还有智充小程序!

Geek_60c26d

银行祖传系统重构实例:创立12年,只支持Python 2,跑着500多个应用程序_架构_THEHFTGUY_InfoQ精选文章