为什么需要关注软件架构
许多软件开发人员不信任架构实践,他们将这些实践与严格和专横的过程以及重要的前期规划和设计联系在一起。
因此,他们相信,如果他们遵循这些实践,可能需要很长时间才能交付一些甚至可能不是客户想要的东西。
他们更愿意专注于理解客户的需求,并通过小而快速的敏捷迭代过程来交付产品。
他们当中有一些人相信,只要遵循了这些过程,架构自然会“出现”,而不需要有意识地进行计划或架构设计。因为存在这些信念,他们可能不认为软件架构是重要的,甚至可能不关心它。
这种架构方法通常可以交付满足客户所需的产品,这是一个好的开始。
但是,如果不显式考虑产品的可持续性,它就有可能衰退,导致产品在自然退役前无法维护。
通过关注关键的质量属性,如性能、可伸缩性、安全性和弹性,有意识的软件架构方法有助于延长产品的生命周期,使其在更长的时期内可持续。
预先架构和紧急架构对比
如果我们正在做的事情是我们非常了解的,并且已经做过很多次了,那么预先设计方法就很有效。例如,建造摩天大楼、挖运河、生产产品或建造桥梁。我们可以应用“最佳实践”,并依赖过去已经在这些事情上验证过的有效方法。
如果我们正在处理一些东西是全新的,并且我们不太了解,或者变化太快以至于还没有“最佳实践”,那么预先设计就不起作用了。在这种情况下,作为科学革命基础的可控性实验可以帮助我们更深入地理解问题和可能的解决方案。最终的解决方案“出现”了,只是它沿着有意识的实验的路径向我们招手。
这两种方法都是有价值的,但适用的场景非常不同,一种可用于处理大部分已知的事情,而另一种可用于在变化的世界中探索新的机会和可能性。
第二种方法的问题在于,可控性实验可能无法在合理的时间内产生可持续的解决方案,并且可能需要进行可接受的返工。软件架构实践可以通过更早地提出更好的问题来指导实验,以减少交付可持续产品的时间和成本,并仍然可以保留敏捷方法的优势。
架构是如何出现的
正如我们在前一篇文章中所讨论的,架构的本质由一组定义和约束产品技术面的决策组成。无论团队采用哪种方法,无论他们是有意识地还是心照不宣地做出决定,这些决定都是存在的。这些决策专注于产品如何处理质量属性需求(QAR)。
QAR 也可以是显式或隐式的,尽管显式的更容易处理并可以确保产品契合它们。例如,用户通常希望在使用产品时能够得到及时响应,而不管有多少人也在使用该产品。显式地声明“响应性”需求以及产品可以支持多少并发用户而不会变成“无法应式”的,将有助于开发团队对他们的技术方法做出更好的决策,比如“系统的速度必须够快”或“系统必须是可伸缩的”这样的声明并不能帮助团队做出更好的技术决策。
评估质量属性需求和设计一个架构来实现这些需求涉及到一些前期规划,这些也是软件系统取得成功的关键驱动因素,原因如下:
软件架构是由质量属性需求驱动的,如果在最初的迭代中没有考虑到它们,通常会在软件系统被部署到初始试验阶段之后(只有少量的用户)出现问题。因此,当必须满足关键的质量属性需求 (如性能、安全性或可伸缩性) 时,可能需要进行重要的架构、设计和代码重构,这可能会出现具有高度易变性的软件架构。此外,如果架构设计没有强有力地实现组件的抽象和隔离,重构的成本可能会飙升。
为解决紧急架构的局限性和满足最初的质量属性需求,进行有意识的架构设计是有必要的。例如,除了提供关于系统实际使用情况的有用信息以及关于架构设计的反馈回路之外,在初始架构设计中加入一个简单的监控框架,这对于确保软件系统的弹性和正确性来说是至关重要的。
重构和过度的组件化会导致解决方案的碎片化,以至于没有人能完全理解发生了什么。有可能不知道正在使用的组件是什么版本,也可能没有记录每个组件的服务水平协议 (Service Level agreement,SLA)。微服务架构为每个服务使用了单独的数据存储,这可能会导致数据一致性问题。单体系统的可持续性较差,但具有高度的内部一致性。这两种架构各有优缺点。
你的软件系统是可持续的吗?
广义地说,实现“可持续性”是软件产品架构工作的重点。如果软件产品能够满足当前需求 (包括 QAR),而不损害满足未来需求的能力,则可以认为该软件产品是可持续的。正如我们在前一节中所述,质量属性需求驱动了架构,满足关键 QAR 对于创建可持续的架构设计来说是至关重要的。不幸的是,随着功能增强的实现和新设计决策的制定,软件系统会随着时间的推移而“磨损”,这可能会延展甚至破坏最初的架构设计。常见的“磨损”原因包括:
由于维护系统的开发人员对系统缺乏理解,最初的设计决策也就过时了。与系统设计相关的决策和假设很少会被准确地记录下来。当人们不再针对系统提出问题或回答问题时,软件系统就开始衰退了。提出问题是评估软件系统健康状况的一种重要技术,如果有知识资源可以回答这些问题的话。
技术债务的累积会导致系统维护不再可行或不再具有成本效益,并且无法实现新的功能。
开发人员试图重用不同组件的代码块,他们认为可以通过对复用代码进行微小的改动来实现新功能。遗憾的是,他们可能无法完全理解原始代码所依赖的架构上下文,也意识不到在不同的组件中重用代码可能会在以后产生不必要的副作用,例如性能、可伸缩性或可用性问题。这些软件变更增加了技术债务,并降低了系统的整体质量,除非技术债务能够迅速得到解决。
技术的发展导致一些软件系统运行在不是为它们设计的技术平台上。一些较老的软件系统经历了“灾难性的成功”,因为它们持续存在的时间比最初计划的要长得多,而且它们的技术债务已经变得非常沉重、难以解决且代价巨大,“偿还”起来非常困难。偿还技术债务的成本可能与完全替换该软件系统的成本类似,甚至有过之而无不及。
失败的假设。逻辑的主体,包括软件系统,最终会因为假设的失败而崩溃,软件开发人员可能没有意识到他们所做的假设。隐藏的假设可以被认为是对系统的约束。关键在于要清楚地阐明所有的假设,并保持信息的更新。质量属性需求本身也是一种需要进行验证的假设,它们的实现需要经过经验的测试和确认,如果可能的话,可以使用自动化。性能、可伸缩性、弹性 (例如,使用类似于 Netflix 猴子军团的框架) 和安全性都是很好的例子。质量属性自动化测试的目标是持续对假设 (例如,实现 QAR 仍然是现实的吗?) 进行测试,并用以指导软件系统的演化。
如果对最初的架构没有很好的理解,即使增加了新特性 (我们可以称之为“架构熵定律”),使用紧急架构创建的软件系统最终也会失去架构完整性。因此,它们可能不再是可持续的。
评估软件架构的适用性
如何知道你的软件系统什么时候磨损了,就像知道你的汽车轮胎什么时候磨损了并需要更换一样?就像医生可能使用许多不同种类的工具来评估个体的健康状况 (心电图、MRI、CT、血液测试、体格检查) 一样,不同的工具可以帮助团队评估软件架构的适用性。旧的系统可能难以理解,因为正如我们前面提到的,它们的设计决策和假设通常没有文档记录,而即使存在文档,也很可能是过时的。理解和评估系统的架构设计通常需要“软件考古”工具和技能。总的来说,有很多工具可以用来评估软件架构的适用性,包括:
架构评审 (特别是对等评审) 是评估软件系统架构设计适用性的有效工具,特别是如果他们关注的权衡 (例如,来自 CMU/SEI 的架构权衡评估方法 (pdf))。
自动化的软件质量评估工具 (例如 CAST),但是人们需要接受它们生成的结果。
代码评审 (特别是自动化代码评审) 对于确保代码质量来说非常重要。结对编程是实现这一目标的另一种方法。
适用性功能实现,例如自动化性能测试。
增强框架实现,包括 Web 服务监控工具,为软件架构提供反馈循环。
技术债务的识别和评估,包括标明会导致技术债务增加的决定。
自动化测试工具 (特别是负载 / 伸缩性 / 弹性测试)。
缺陷趋势分析 (这是技术债务的代理),需要使用一致的方式捕获数据,目标是识别不稳定性。
生产事故趋势分析——与缺陷趋势分析具有相同的要求和目标。
安全测试工具。使用这些工具的目的是找出风险暴露点。
结 论
在“前期大设计”和敏捷实践之间长达 20 年的争议中,软件开发人员努力在这两种方法之间找到一个有意义的平衡点,并从有意识的架构活动转向自组织团队的架构设计。因此,他们常常认为软件架构并不是那么重要。更多地意识到架构当中存在的隐式决策,并迫使这些决策变成显式的,这有助于开发团队利用他们从 Sprint 和迭代中获得的经验数据做出更好、更明智的决策。现代架构实践,如持续架构和演进架构,提供了可以帮助做出显式架构决策的工具,让开发人员能够交付更可持续的软件产品。
欲了解更多信息,请参考 Murat Erder、Pierre Pureur 和 Eoin Woods 合著的“Continuous Architecture in Practice”,以及 Murat Erder 和 Pierre Pureur 合著的“Continuous Architecture: Sustainable Architecture in an Agile and Cloud-Centric World”。
作者简介:
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 年出版) 的合著者,并发表了许多文章,还在多个软件架构会议上做演讲。
Kurt Bittner拥有超过 30 年在短反馈驱动周期内开发软件的经验。他帮助许多组织采用敏捷软件交付实践,包括大型银行、保险、制造和零售组织,以及大型政府机构。他曾为包括 Oracle、HP、IBM 和微软在内的大型软件交付组织工作,曾是 Forrester Research 的技术行业分析师。他的工作重心是帮助企业建立强大的、自组织的、高性能的团队,为客户提供他们喜爱的解决方案。他写了四本关于软件开发的书,包括“The Nexus Framework for Scaling Scrum”。他现居科罗拉多州博尔德市,担任 Scrum.org 的企业解决方案副总裁。
https://www.infoq.com/articles/care-about-architecture/?
作者 | Pierre Pureur, Kurt Bittner
译者 | 明知山
策划 | 丁晓昀