云栖号资讯:【点击查看更多行业资讯】
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!

在传统企业甚至互联网企业中往往存在大量的遗留代码,这些遗留代码大多都能够正常工作,有的可能还运行着关键业务或者持有核心数据。但是,大部分遗留代码通常经常存在技术陈旧、代码复杂、难以修改等特点。随着时间的推移,遗留代码的维护和管理的成本越来越大。在全面转型微服务的今天,这些遗留代码该如何处理呢?Tomasz Kania-Orzeł 为我们阐述了升级遗留代码的最佳实践,我相信,这篇文章对于拥有大量遗留代码的企业 / 组织很有借鉴意义。

“我在 Ruby on Rails 上有一款可以追溯到 2011 年的应用,在过去五年来没有添加任何新功能。而且它现在运行死慢死慢的,随着我们用户群不断地增长,它已经几乎不能提供服务了。您能帮我们解决这个问题吗?”

这是我在 Monterail 的客户那儿遇到的最常见的情景之一。这种难以维护且存在安全漏洞的遗留代码,对于必须使用它的企业,以及必须处理它的开发人员(比如我们)来说,真不啻噩梦一场。在我担任软件工程师十年左右的时间里,有过很多机会让我得以观察一些开发人员为了更新 Web 应用程序中的遗留代码而进行的技术转变,这些技术转变有成功,也有失败。例如,这可能意味着,从某个框架的版本 2 升级为版本 6,或者从 Ruby 变更为 Python,或者从单体应用转变为微服务架构,或者从手工构建更改为持续交付。为了完成一次无痛(或至少不那么痛苦)更新,你必须确定进行更改是否有必要,确定最合适自己的方法并承诺长期践行。

应该何时进行变更?

糟糕的性能是做出技术变更的原因。另一个原因就是你所使用的技术的普及程度逐渐或突然下降了。毕竟,如果市场上能够支持你工作的开发人员越来越少,那么你的技术存在被封闭的风险就越来越大。有些人早在 2010 年就用 Backbone 构建了他们的应用程序,如今却在努力解决“模型 - 视图 - 控制器”的问题,而其他人都在使用基于组件的框架,如 React 或 Vue 等。如果你选择的框架正在失去积极的支持,那么风险就会更大。还记得 AngularJS 吗?2018 年 7 月,它就进入了长期支持阶段,这意味着 Google 不会再合并新的功能或修补程序,哪怕是一个微小的突破性改动。

译注:“模型 - 视图 - 控制器”(Model–view–controller,MVC),是是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。MVC 最早由 Trygve Reenskaug 在 1978 年提出,是 Xerox PARC 在 20 世纪 80 年代为程序语言 Smalltalk 发明的一种软件架构。MVC 的目的是实现一种动态的程式设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。除此之外,MVC 通过对复杂度的简化,使程序结构更加直观。

当你的技术在人力或机器成本方面过于低效、过于昂贵,这不仅是发起技术变更的一个好机会,而且也可能是你在技术变得不可挽回之前修复它的最后机会。你永远不会想达到这样的地步:创建一个新功能是完全不可行的。欧洲电子商务公司 Zalando 正努力快速扩展其单体 PHP 应用程序,却 无法以快速或高效的方式提供新功能。这促使他们在 2016 年从单体架构应用转向微服务,使不同的团队能够以更快的速度交付功能。

应该如何进行变更

一旦确定你正在开发的产品需要升级,那么就是时候对变更方向做出明智的决定了。代码一旦编写就会成为遗留代码, 没有人能保证你当时编写所用的技术在未来不会失去支持或变得过时。(安息吧,AngularJS。)因此,变更应该支持未来的灵活性。以下是一些选项:

选项一:大爆炸式的重写

第一个也是最明显的选项,就是大爆炸式的重写:从头开始更改代码库,并在一次转换中切换所有用户。但是,完全重写是非常耗时的,而且必然也会产生相当巨大的成本。你也有可能最终得到的是一款在几个月甚至几年内都不适合发布的应用程序,并且在这个过程结束之前,你都无法看到最终结果。另外,应用程序越大,开发者在重写过程中提供维护和添加新功能的难度就越大。如果有文档和技术知识的话,向大型代码库添加新功能就像在公园里散步一样简单。若没有这些的话,要做到这些,真的很难。

选项二:凤凰涅槃

第二个选项是在现有代码库中添加使用新技术构建的新功能。理想情况下,你不应该触及旧技术,而应该将所有新功能分离开来。但不幸的是,这样的原始结果相当罕见:新功能几乎总是需要与旧功能集成。这也需要一个详细的计划,因为事情很复杂,没有周密计划的话很难做好。在复杂的架构中创建新的组件,需要大量关于遗留应用程序中组件运行情况的信息。你需要一个广阔的视角,从新旧两个角度看待这项技术。

使用单体应用程序,你可以在单独部署的新代码库中创建新功能,同时使用与新代码和遗留代码交互的单个数据库来存储数据。这个解决方案看起来很简单,但它能否取得长期成功,要取决于你的承诺是否坚如磐石。(特别是当你的整体系统受到机器性能或并发性问题的影响时,就需要考虑这些问题。)例如,如果你的单体应用程序开始获得更多的用户,那么,单个数据库可能会成为瓶颈。(另一方面,云端中的数据库可以扩展。)由于原始代码库的长期脆弱性,特别是考虑到潜在的安全漏洞或 bug,这种架构并不能持久。实际上,让过时的代码保持原样就意味着你在等待它最终永远失败。

选项三:混合方法

重写整个代码库是一个极端的想法,而且往往考虑不周。在旧代码库上添加新功能更可行,但会带来严重的副作用,例如,如果你的遗留代码是基于较旧的框架版本,那么就会出现安全问题。那么,还有什么事情是你可以做的,而且不那么昂贵,或者不那么危险的? 你还有其他选择吗?

我推荐一种混合方法。这一选项,就像大爆炸式重写一样,也需要对整个旧代码进行变更。但与第一种选项不同的是,重写应该是在一段时间内展开(比如说几年),以最大限度地减少技术债务和财务成本。这种渐进式方法将基于你的愿景,这一点至关重要。你需要知道首先要改变什么:有些功能是核心的,对业务至关重要,而其他功能则更多的是扮演辅助角色。有了明确的目标,在多个层面上工作就会变得更容易。例如,你是否仍然计划在这个转换过程中发布一项新功能?如果是这样的话,你就需要在计划中考虑到这一点。如果没有清晰的路线图,你的代码最终将会变得一团糟,这将会使开发者更难理解。

对我来说,这种方法关乎未来和可扩展性:而且它最容易使用微服务来实现。假设你的遗留代码库是新的微服务生态系统中的一个元素。当然,它太过于庞大,过于复杂,不可能是真正的微服务,但它可以像微服务一样与新功能进行通信。为了处理这种安排,你需要创建 API 或“桥”这样的接口,以允许遗留代码与新技术进行通讯。当你以单独的微服务形式添加新功能时,它们将会一点一点地吞噬遗留代码的业务逻辑。虽然你可以通过向遗留的单体应用程序添加新功能来实现类似的功能,但此举可能会造成技术债务,并失去灵活性。

几乎所有的解决方案都有副作用,包括这种方法。但是我们需要知道如何将副作用最小化。对于 Web 应用的前端,反向代理可以缓和这一变更带来的副作用。使用这种方法,你甚至可以在不触及遗留软件的情况下,替换 Web 应用中为单个 URL 提供服务的逻辑。但这种技术有其自身的要求,例如,如果你有用户登录的话,就应该维护页面之间的状态。我们始终需要存储状态,但在这个解决方案中,我们需要在两个应用之间移动或共享状态。这很难维护,但你还是可以得到更具弹性的基础设施。

更复杂的更改需要对基础设施进行改进,比如,创建一个前端服务器层,你可以从其中呈现来自不同源的应用程序片段,如上面的微服务示例。基于 XML 的标记语言 ESI(Edge Sides Includes)可能适合这项任务,而 Varish 或 Nginx 然后,为了确保你的应用在用户群增长时能够保持性能,请创建负载均衡器和基于上下文的独立数据库,这些数据库在微服务或宏服务中单独使用。

创造一个能够支持这种安排的灵活环境也是一个挑战。转移到微服务时,你只需在基础设施上投资一次,但你将需要进一步支持这种架构的维护。尽管如此,它可能仍然比重写所有代码要便宜得多。

如果你的主要目标是创建一个易于维护的生态系统(而不是关注性能第一,维护第二),你还需要在开发过程中确定系统的关键元素,并创建路线图来对它们进行更改。在这个过程中引入一些持续集成和部署的魔法,其中,CI 和 CD 流程可以在没有 QA 或开发人员的帮助就能自动进行,然后你最终将得到一个结构清晰、易于修改和调整的成熟软件。

当然,这种混合方法并不是世界上唯一可行或正在使用的选项。但是,代码库的增量更改最终导致了完全重写,你得以能够使用工作代码,从而使业务保持安全,同时,微服务使不同团队能够独立地交付新的和不同的功能,提供了一个为长期使用而设计的过程和架构。

要做持久的更改需要什么?

你可能会看着我的首选解决方案,然后心想,“嗯,这有点过于工程化了”,或者“我没有一个团队能胜任这种工作”,或者“这对我的平台来说太过于复杂”,或者甚至“这不是纯粹的微服务架构!”我并不反对你这些想法,但我确实认为,升级你的技术将会迫使你作长远考虑。

我提供的并不是快速解决方案。相反,混合方法为你提供了基于工作基础之上的新技术。通过逐步转向微服务,增量更改允许你轻松地更新应用程序,并利用最新的框架,所有这些都不会迫使你在可靠性上作出妥协。那么,你准备好重新构建你的软件了吗?

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/zhibo

立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:yqgroup@service.aliyun.com 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。

原文链接
本文为云栖社区原创内容,未经允许不得转载。

升级遗留代码的最佳实践相关推荐

  1. Java Web应用的代码分层最佳实践

    转载自 Java Web应用的代码分层最佳实践 代码分层,对于任何一个Java Web开发来说应该都不陌生.一个好的层次划分不仅可以能使代码结构更加清楚,还可以使项目分工更加明确,可读性大大提升,更加 ...

  2. 编写高性能Java代码的最佳实践

    编写高性能Java代码的最佳实践 摘要:本文首先介绍了负载测试.基于APM工具的应用程序和服务器监控,随后介绍了编写高性能Java代码的一些最佳实践.最后研究了JVM特定的调优技巧.数据库端的优化和架 ...

  3. 前端代码标准最佳实践:CSS篇

    上一篇<前端代码标准最佳实践:javascript>发表后,大家讨论还是很热烈,从侧面体现了前端工程师对写标准的前端代码的重视程度很高.这些最佳标准实践并不是那个权威组织发布的,而是由大量 ...

  4. 前端代码标准最佳实践:HTML篇

    Web前端代码中,HTML是根本,CSS和JavaScript也是围绕着既有的HTML结构来构建,所以良好的HTML代码结构,除了提高了HTML代码的可读性,可维护性和执行性能之外,也可以让相对应的C ...

  5. 前端代码标准最佳实践:javascript篇

    2019独角兽企业重金招聘Python工程师标准>>> 前言 最近一直重构项目的前端代码,也参考了各种前端代码的最佳实践,目的是让前端的HTML,CSS,Javacript代码更符合 ...

  6. 高性能Java代码的最佳实践

    高性能Java代码的最佳实践 前言 在这篇文章中,我们将讨论几个有助于提升Java应用程序性能的方法.我们首先将介绍如何定义可度量的性能指标,然后看看有哪些工具可以用来度量和监控应用程序性能,以及确定 ...

  7. Spotfire在文本区域添加自定义JavaScript代码的最佳实践

    这边文章包含了如何在TIBCO Spotfire分析文件的文本区域中以一种可支持和可维护的方式来开发自定义JavaScript代码的最佳实践和建议,因此,这些分析文件将持续与TIBCO Spotfir ...

  8. Java Web应用的代码分层最佳实践。

    代码分层,对于任何一个Java Web开发来说应该都不陌生.一个好的层次划分不仅可以能使代码结构更加清楚,还可以使项目分工更加明确,可读性大大提升,更加有利于后期的维护和升级. 从另外一个角度来看,好 ...

  9. java replaceall正则表达式_编写高性能Java代码的最佳实践

    作者:Eugen Paraschiv 翻译:雁惊寒https://dzone.com 摘要:本文首先介绍了负载测试.基于APM工具的应用程序和服务器监控,随后介绍了编写高性能Java代码的一些最佳实践 ...

最新文章

  1. 3分钟内快速部署MySQL5.6.35数据库实践
  2. mongo 脚本对应的C#实现方式(待整理)
  3. 闲诗一首:《扬州即行》
  4. MySql中如果某一列中含有NULL,那么包含该列的索引就无效了?
  5. mint-ui 中 Infinite scroll 在tab-container中使用数据全部加载的问题
  6. 风险评估资产重要性识别_如何有效的进行风险评估?
  7. 用sed和awk实现将文本中的上下两行合并为一行(转载)
  8. java swing mysql实现的员工工资管理系统项目
  9. 不会python怎么了?靠敏捷BI和数据可视化,照样去阿里腾讯
  10. maplesoft maple 2021 安装教程
  11. Maya: Render Setup System Maya教程:渲染设置系统 Lynda课程中文字幕
  12. 网络云存储技术Windows server 2012 (项目十六 基于iSCSI传输的配置与管理)
  13. 吉林大学计算机学院高尚教授,高尚 - 吉林大学 - 计算机科学与技术学院
  14. 专访吴军:“腾讯无2B基因,谷歌太平庸”,“我说错了吗?”
  15. C语言电码,翻译莫尔斯电码
  16. Go语言——没有对象的面向对象编程
  17. 游戏俄罗斯方块(c语言)
  18. pythonIED -pycharm基础知识
  19. VBS 请求WebAPI接口_C#进阶系列——WebApi 路由机制剖析:你准备好了吗?
  20. datatable 属性介绍

热门文章

  1. python多进程和多线程使用场景_Python36 多线程、多进程的使用场景
  2. 【LeetCode笔记】494. 目标和(Java、动态规划、背包问题、滚动数组)
  3. mfc打开一个.txt文件并进行处理_文件处理方法Python
  4. java s结尾的工具类_FilenameUtils工具类
  5. chrome控制台如何把vw显示成px_你可能不知道的chrome调试技巧
  6. centos7 关闭selinux_Devops之LDAP部署安装(centos7+openLDAP+PhpLDAPAdmin)
  7. set和map去重调用什么方法_你真的了解ES6的Set,WeakSet,Map和WeakMap吗?
  8. tinyxml 读取文本节点_在Windows下使用TinyXML-2读取UTF-8编码包含中文字符的XML文件...
  9. matlab画出周期为2的方波图形 傅立叶级数_高等数学系列R之四:傅立叶级数及变换...
  10. java无锁消费者框架_无锁并行框架多生产者多消费者模型