QCon 演讲火热征集中,快来分享技术实践与洞见! 了解详情
写点什么

银行祖传系统重构实例:创立 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:023433
用户头像
王强 技术是文明进步的力量

发布了 843 篇内容, 共 453.2 次阅读, 收获喜欢 1760 次。

关注

评论

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

Neo4j CEO Emil Eifrem 解读图数据平台引领数据库未来十年的发展

Neo4j 图无处不在

neo4j 图数据库 知识图谱 图可视化引擎 图数据

图数据技术护航网络安全

Neo4j 图无处不在

网络安全 neo4j 图数据库 知识图谱 图算法

天翼云Serverless边缘容器下沉服务 促进企业聚焦业务创新

天翼云开发者社区

云原生主题学习月|共同学习全球领先的亚马逊云科技云原生课程,组团共学拿奖励~

亚马逊云科技 (Amazon Web Services)

云原生 培训与认证

跨越速运如何构建实时统一的运单分析

StarRocks

#数据库

面试官:说说电商系统订单超时自动取消怎么实现?你有几种方案?

程序员小毕

程序员 面试 程序人生 后端 架构师

深究用户模式锁的使用场景(异变结构、互锁、旋转锁)

C++后台开发

数据结构 多线程 linux开发 C++开发

企业内部统一的移动平台,实现安全高效的业务移动化

BeeWorks

嘉为科技吴文豪:重塑运维系统,跨越烟囱式建设的陷阱

嘉为蓝鲸

运维 #WeOps

Kotlin伴生对象(Companion Object)

子不语Any

android kotlin 11月月更

元器选型攻略之 电阻

元器件秋姐

元器件知识 元器件科普 电阻 电阻定义 常见电阻

Kotlin作用域函数[Scope Function](上)

子不语Any

android kotlin 11月月更

生活中常见的新北洋打印机:多场景赋能美好生活

科技热闻

数字先锋| 一朵云,将温暖传递千家万户

天翼云开发者社区

老板让我在Linux中使用traceroute排查服务器网络问题,幸好我收藏了这篇文章!

wljslmz

Linux 网络故障 11月月更 traceroute

亚信科技亮相南京软博会,数智赋能百行千业

亚信AntDB数据库

AntDB aisware antdb AntDB数据库

可视化:如何选择数据可视化图表?

2D3D前端可视化开发

数据可视化 可视化大屏 可视化图表 可视化工具 sovitchart

APP以监听投广?中央APP治理专项组测评揭晓答案!

科技热闻

通过飞书审批 Bytebase 工单

Bytebase

数据库 sql DevOps SQL审核 SQL审批

玩转云端| 数据库安全服务,为数据库资产构建“最后一道防线”!

天翼云开发者社区

企业数字营销和运营如何效果更好?瓴羊Quick BI成为了不错的选择

小偏执o

Kotlin作用域函数[Scope Function](下)

子不语Any

android kotlin 11月月更

制造业的敏捷分析,还需要使用瓴羊Quick BI

对不起该用户已成仙‖

ZooKeeper 避坑实践:如何调优 jute.maxbuffer

阿里巴巴云原生

zookeeper 阿里云 云原生

微服务治理的3种方式

穿过生命散发芬芳

微服务治理 11月月更

嘉为科技张敏:一文讲清场景工程方法论及运维组织能力内化

嘉为蓝鲸

运维 数字化

云原生主题学习月|成为社区领学员,解锁专属奖励及超多数量社区学员奖品!

亚马逊云科技 (Amazon Web Services)

云原生 培训与认证

天翼云混合云容灾技术解析

天翼云开发者社区

焱融科技为国家重点实验室打造海量高性能存储

焱融科技

云计算 分布式系统 高性能 文件存储

瓴羊Quick BI在商业智能BI发展趋势方面如何?

对不起该用户已成仙‖

老工程师荐读!PCB设计避坑指南

华秋PCB

PCB PCB设计

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