遗留应用程序经常被卡在慢车道上:老迈而脆弱,技术老化,缺少支持,也很难受益于像持续交付这样的先进概念。由于遗留系统潜在的不稳定性,它们更需要采用最小可行产品(MVP)、最小可行架构(MVA)等概念。
这怎么可能呢?大多数遗留应用程序都是单体的,无法增量发布。
其实系统的每发布一个版本都是一次实验,都是为了验证该版本是否提高了客户体验。遗留系统也一样,它的每个版本也都可以视为一个 MVP,提供了期望交付的价值。因此,每个版本也有一个 MVA。采用 MVP 和 MVA 后,团队可以聚焦测试,解决客户真正需要解决的问题。
因为 MVP 的概念通常与新产品联系在一起,所以最好把现有应用程序的每个新版本都看作是最小可行增量(minimum viable increment),或者是团队认为能够提高客户体验的最小变更集。鉴于 MVP 这个术语大家已经很熟悉了,我们后面继续使用。
之前的文章已经介绍过,MVA 是使 MVP 满足质量属性需求(QAR)所需的最小架构。对于我们来说,架构主要关乎架构决策,对于遗留应用程序的每个版本,MVA 是使该版本支持 QAR 所需的最小变更集。
MVP 发布就绪标准通常关注的是,这个版本提供的价值是否能满足客户的预期;MVP 不是“技术性的概念验证”。而 MVA 是否发布就绪则视评估结果而定,即对遗留应用程序所做的变更是否能确保这个版本满足应用程序的 QAR,以及这样做是否能持续满足客户的需求。
图 1 MVP&MVA 为观察遗留系统提供了一个“透镜”
流程挑战:
对于任何发布,尤其是组织依赖的应用程序,其中一项标准是,应用程序必须通过一组测试(理想情况下自动测试),以确保满足 QAR。手动运行测试评估 QAR 太过繁琐,而且容易出错,所以并不可靠。缺少通过自动化测试确定一个版本是否满足功能需求和 QAR 的手段,是妨碍组织小增量交付价值的因素之一。
还有其他一些因素妨碍组织进行小增量发布,导致他们发布变更的增量相对较大而且复杂。这些因素包括:
缺少有效的构建、测试和发布自动化。如果交付管道的一大部分是手动的,那么手动步骤引发的延迟和错误会让组织做任何事都快不起来。即使各部分都自动化了,团队交接导致的延迟也会拖慢整个过程。这类问题有许多解决方案,但需要组织改变工作方式,有时候还要改变组织架构。
应用程序之间紧耦合。当应用程序共享数据或组件时,对其中一个的变更就需要重新发布另一个。如果组织的遗留系统是紧耦合的,那么小变更就很难做,因为可能所有的应用程序都需要重新发布,他们承担不起这样的时间或精力成本。
繁琐的发布审批流程。由于在某种意义上,许多遗留系统已经成为业务关键系统,所以对它们的变更经常需要高级业务主管来审批,而这些人可能并不真正了解与之相关的技术问题。如果要让他们认可变更的范围和风险,那么将变更解释成通俗易懂的语言所耗费的时间和精力就会非常多。
监管约束。受监管行业的组织可能必须获得监管部门的批准才能发布新产品,或者大幅改变现有产品。他们还需要提供客户使用这些产品的监管报告。他们很难利用 MVP 的概念,因为监管机构通常希望了解新产品或变更后产品的方方面面。用真实的客户体验数据来回答关键问题是使用 MVP 的全部原因,因此,组织陷入了一种两难境地;他们不能发布产品来测试 MVP,他们也无法在没有经验的情况下完全定义新产品(或变更后的产品)。由于监管约束的存在,这些公司似乎注定要在客户不需要的产品上过度投资,因为它们无法尽早、渐进地测试创意。
专业知识的短缺(或流失)。在某些情况下,组织无法真正了解遗留应用程序的业务逻辑或所采用的技术。解决这个问题的一个方法是,用更有效的现代解决方案逐步取代遗留应用中仍然有价值的部分,一次提供一项客户成果。在这个过程中,组织可以发现遗留应用程序的许多功能不再重要或需要,但这需要时间来解决,短期内,留给组织的会是一个更加碎片化的解决方案,由于总会有其他挑战出现,所以也有可能永远无法完全解决。
除了监管约束之外,其他问题都可以解决,但需要时间和相关人员的共同努力。
偿还技术债务的困境
当你有机会的时候,偿还债务,听起来还不错,对吗?
有时候,组织会设法做一些额外的技术工作,目的是实现现代化或减少技术债务,为此,他们可能会做一个合理化的解释,“无论如何,我们都要处理下应用程序的那个部分,既然要干,就要干利索。”虽然出发点是好的,但基本可以确定这个对定很糟糕,它会导致不必要的成本和延误,因为一旦开始,就很难停止。
这就是 MVA 的好处所在:它提供了方法,让每个人都可以决定必须做出哪些变更,以及不应该做出哪些变更,至少目前还不能。如果变更是一个版本交付所必需的,那么它就是 MVA 的一部分,否则,它就不是。
有时候,考虑到代码的状态,团队可能会在查看应用程序所需的变更后,决定完全重写。这时,将 MVA 概念应用于遗留应用程序,问一下,这些变更是否真的是增量改进客户价值所需要的,就可以缓解这一问题。
确实,应用程序可能已经太过久远,无法扩展了,但根据我们的经验,“完全重写”几乎从来没有成功过。(从来没有看到,甚至没有听说过,这些项目中有哪个真正交付了。)如果真的要从头开始,也不要重写现有的系统;相反,应该立足于客户期望的成果,寻找不同的交付方式。
可行性和发布范围
MVA 会影响 MVP,对遗留应用程序而言尤其如此。MVA 和 MVP 都涉及一个重要的词:可行性。如果在评估为了交付 MVP 而需要对应用程序做出的变更时发现,要以一种可持续的方式实现 MVP 太过昂贵,那么就需要重新考虑 MVP 并进行修改。
利用 MVA 方法:使用 QAR
最小可行架构(“MVA”)(参阅我们的文章“最小可行产品与最小可行架构”)提供了一种方法,让你可以确定为了交付 MVP 所需的量化程度。将创建 MVA 作为 MVP 交付工作的一部分,有助于评估技术可行性,并为产品提供一个稳固的基础,而且可以随着产品的演化进行调整。使 MVA 架构决策透明化,帮助组织更好地理解为什么要做出某些选择,有助于做出更好的决策,使产品适应不断变化的市场条件和不断发展的客户需求。
QAR 驱动策略:你所要做的最重要的 MVA 架构决策可能是选择最小数量的架构组件,使 MVP 能够处理与产品/系统特性相关的 QAR,例如:
并发性——并发用户、传感器和其他设备的数量,产品必须对这些事件做出响应。。
吞吐量——给定时间段内的事务量或产品所能处理的数据量。
延迟和响应性——产品响应事件的速度。
可扩展性——系统处理增量工作负载的能力,方法是通过增加系统成本增加工作负载,通常是线性关系。
持久化——产品必须存储和检索的数据的吞吐量和结构,通常会涉及不同数据存储技术的选型(SQL DBMS、NoSQL DBMS 等)。
安全——产品如何通过保密性、完整性和可用性来保护数据免受未经授权的使用或访问。
监控——与如何检测产品有关,目的是方便提供产品支持服务的人及时了解产品无法满足 QAR 的情况,并防止出现重大的系统问题。
平台——产品如何满足 QAR 以及与之相关的系统资源约束,如内存、存储、事件通知等。举例来说,实时嵌入式产品(如数字手表或自动刹车系统)与基于云的信息系统约束截然不同。
用户界面——产品为用户提供的交互方式;例如,虚拟现实界面的 QAR 与二维图形用户界面就有很大的差别。这些决策可能影响到上面提到的其他 QAR。(GUI、VR、命令行或其他类型的界面。)
举例来说,假如你计划构建一个移动应用来支持产品在新市场的投放,使用开源或商业框架来快速交付 MVP,并创建一个访问遗留系统数据的接口。在此过程中,遗留应用程序将不可避免地要处理设计时未考虑的工作负载。新增的工作负载会导致遗留系统失败吗?额外的工作负载会威胁到遗留系统满足现有用户 QAR 的能力吗?移动应用是否改变了遗留系统的 QAR?
访问遗留系统数据的新应用程序会改变遗留系统的 QAR,因为它会改变遗留系统的工作负载、吞吐量、响应能力和安全相关的需求。遗留系统不是为了支持新应用程序的用户需求而构建的,在确定遗留系统的修改程度时,必须考虑这些需求。在某些情况下,无论做多少工作都无法使遗留系统满足新的 QAR,此时,必须替换遗留系统才能满足新应用程序需要。
实证是评估这些问题的强大工具,新移动应用的每个版本,至少都会创造一个机会来评估遗留系统的架构是否能够支持新增需求。开发团队很可能需要修改遗留应用程序来满足新的 QAR。将对遗留应用程序的更改作为移动应用 MVA 的一部分,有助于团队决定需要多少变更才能完成移动应用 MVP 发布目标。
QAR 是一种非常有用的工具,可以诊断出遗留系统哪里可以改进。QAR 可以帮你将变更范围最小化,即仅支持 MVP。这有助于防止陷入“彻底重写”的深渊,因为那样做成本高昂、费时且容易失败,而且经常是不必要的。
限制新功能的范围。不要试图超出 MVP 的范围,虽然有些功能看似很好,但对 MVP 来说没有必要。领域驱动设计(DDD)是一种非常强大的软件开发方法,也是一种非常有效的确定 MVP 新功能范围的技术,它可以精确限制 MVP 所需功能的范围。
尽量解耦和简化系统组件。遗留系统维护的挑战之一是缺少模块化,其中许多代码在编写时还不流行模块化,大多数代码重用是通过“复制和粘贴”实现的。虽然重构这些冗余代码很有诱惑力,但请限制在支持 MVP 所需的范围内。当确实需要重构或替换代码时,务必要保证新代码的模块化和可重用性。对此,微服务就很适合,在某些情况下,Serverless 也可以实现同样的效果。在需要修改的应用程序中,将代码替换为调用共享组件或服务,同时要记录替换过程,以防其他应用程序也做类似修改。这样,如果其他团队必须修改应用程序以使用类似的服务时,就可以省点事。
将新功能从遗留系统中转移出来。除非在遗留系统中实现新功能非常简单并且可持续,否则就用现代技术开发与 MVP 相关的新业务功能,比如基于云的服务。如果新功能必须从旧程序中发起,则可以将新工作编写成一个新组件或服务,然后从旧代码中调用它。随着时间的推移,上面提到的解耦工作以及将新代码向现代技术迁移,将逐步减少你需要担心的遗留代码量。
使用诸如“绞杀者模式”或“抽象分支”这样的模式,并在适当的时候实现一个网关将请求路由到新的 MVA 组件,会对这类迁移有所帮助。但任何方法和工具都有局限性。例如,“绞杀者模式”适合从单个应用程序迁移定义良好的功能块,但如果要替换的基础设施会影响数十个应用程序,那么这种方法就不合适了。
识别“死代码”并找机会清除它。使用静态和动态代码分析工具,找出在 MVA 的范围内,遗留系统中哪些部分用不到了。将死代码作为清除目标(但不要立马扎进去做——小心伤及无辜)。这也可以推广到报表——旧系统生成了大量的报表,其中一些(或许多)可能没人用了;业务可能已经变了,但系统没有同步修改。标示无用代码,让团队更容易看清楚哪些代码会影响 MVA。部署的代码越少就越可靠,系统占用的关键系统资源也越少。即使团队决定不删除代码,也可以供其他团队未来做决策时参考。
组织技术标准使遗留系统永久化。组织技术标准可以限制不支持的基础技术配置,但如果一个标准使用太久,就会使组织停留在过去,无法适应未来。MVA 可以帮助组织了解新技术是否真的可以帮助团队交付特定的 MVP。有了 MVA 提供的证据,组织就可以确定 MVP 是否真有战略意义,技术标准是否有修改的必要。
应该在哪里存储 MVA 数据?MVA 其中一项关键决策是为与 MVP 相关的数据选择数据存储。其中一些数据在遗留数据存储中,在大多数情况下,还需要捕获和存储其他一些数据。这些数据既可以合并到遗留数据存储中,也可以存储在新实现的、更先进的 DBMS 中。第一种方法简化了数据聚合和报表,但缺点是扩大了本来就可能淘汰的技术的使用范围(例如 IMS/DB)。如果为支持 MVP 添加的数据只占现有 MVA 遗留数据的一小部分,那么这种方法可能比较合适。第二种方法限制了遗留数据存储的使用,使得数据聚合变得复杂,如果要添加的数据占现有 MVA 遗留数据的比例很大,则应该考虑使用这种方法。第二种方法的一种变体是将现有的 MVA 遗留数据迁移到新的 DBMS。但是,迁移数据比迁移功能要困难得多,因为数据可能被 MVA 范围之外的多个遗留应用程序使用。这样做可能会超出 MVA 的范围。
小结
遗留系统有点像一个仍在蓬勃发展的古老都市:新旧混合的系统维护都很难跟上,更不用说为了适应快速变化的需求而进行大规模地翻新了。找到一种可以持续调整遗留系统的方法,对于企业适应不断变化的世界至关重要。
MVP 和 MVA 的概念不仅适用于新应用程序,它们也为限定遗留系统的变更范围提供了新的新视角,可以防止短时间内承担太多变更任务。实际上,在第一个主要版本发布之后,每个新应用程序都会变成“遗留应用程序”,重要的是,要随着它的演化找到限制变更范围的方法。
MVA 方法可以帮你了解一项新技术对支持 MVP 有多重要,从而帮助组织评估和修改其技术标准。它让你可以用真实数据来挑战技术标准,而不仅仅根据偏好和想法。
创建 MVA 的过程可以帮助团队评估遗留系统的哪些部分现在就需要调整,哪些部分可以再等等。为了实现应用程序演化,组织投入重金进行“完全重写”,但失败了,事后看来,这是不必要的。确定哪些部分现在就必须进行调整,哪些部分可以再等等,这很有用,因为它让组织可以更好地理解其技术债务,筛掉那些不必要的工作。
由于遗留应用程序经常是任务关键型系统,所以需要特别关注可持续性。担心遗留应用程序变得不稳定,许多组织都不敢对它们进行必要的增量改进,这使得它们更加脆弱和风险重重。关注可持续性 QAR,提高团队改进应用程序所需的技能,有助于使应用程序随着时间的推移更具弹性。
最后,务必要记住,在许多情况下,今天的“遗留”应用程序可能就是近期开发的。遗留应用程序可以有 40 年前编写的应用;也可以是 10 年前编写的,或者更近。一旦应用程序不再持续更新,它就开始退化。考虑将 MVA 作为每个新版本的组成部分有助于延长应用程序的生命周期。
作者简介:
Kurt Bittner 拥有 30 多年在短周期反馈循环中交付可工作软件的经验。他曾帮助许多组织采用敏捷软件交付实践,包括大型银行、保险、制造和零售组织以及大型政府机构。他还曾就职于大型软件交付组织,包括甲骨文、惠普、IBM 和微软,并曾是弗雷斯特研究公司(Forrester Research)的技术行业分析师。他致力于帮助组织建立强大、自组织的高效团队,交付受客户欢迎的解决方案。他写过 4 本与软件开发相关的书籍,其中包括《Nexus 规模化 Scrum 框架》。他现居科罗拉多州博尔德市,并担任 Scrum.org 的企业解决方案副总裁。
Pierre Pureur 是一位经验丰富的软件架构师,拥有广泛的创新和应用开发背景、丰富的金融服务行业经验和咨询经验、全面的技术基础设施知识。他曾担任一家大型金融服务公司的首席企业架构师,领导大型架构团队,管理大型并发应用开发项目,指导创新计划,以及制定战略和业务规划。他是“Continuous Architecture in Practice: Scalable Software Architecture in the Age of Agility and DevOps”(2021 出版)和“Continuous Architecture: Sustainable Architecture in an Agile and Cloud-Centric World”(2015 出版)的合著者,发表过许多文章,并在多个软件架构会议上发表过关于这一主题的演讲。
原文链接:
Chipping Away at the Monolith: Applying MVPs and MVAs to Legacy Applications
相关阅读:
评论