演进式架构

一直以来,由于软件架构涉及范围广且内涵不断变化,开发人员不断尝试给它一个简洁的定义。Ralph Johnson 就将其定义为“重要的东西(无论那是什么)”。架构师的工作就是理解和权衡那些“重要的东西”(无论它们是什么)。

为了给出解决方案,架构师工作的第一步是理解业务需求,也即领域需求。这些需求是使用软件来解决问题的动机,但终究只是架构师在构建架构时需要考虑的因素之一。架构师还必须考虑其他很多因素,其中一些比较明确(比如清楚地写在性能服务水平协议里),还有一些则隐含在商业活动中不言自明(比如公司正着手并购重组,软件架构显然也要有变动)。所以对于软件架构师来说,架构水平体现了他们在权衡业务需求和其他重要因素后找到最佳方案的能力。软件架构涵盖了所有这些架构因素,如图 1-1 所示。

图 1-2:流行编程语言的演进过程

无论是在软件开发的哪个方面,比如编程平台、编程语言、运维环境、持久化技术等,我们都知道改变会持续发生。虽然无法预测技术或领域格局何时会改变,或哪些变化会持续下去,但我们清楚改变是不可避免的。因此,我们应该在构建系统的过程中对这一点保持清醒的认识。

如果整个体系持续地以出乎意料的方式发生变化,预测变化就变得不可能了,那么用什么来替代固定计划呢业架构师和开发人员必须学会适应变化。做长期计划有一个隐含的原因是财务上的考虑,因为以前软件变更的成本很高。但是,现代工程实践通过自动化和其他先进实践(例如 DevOps)降低了软件变更的成本。

多年来,一些聪明的开发人员发现系统的某些部分相对而言更难修改。这便是将软件架构定义为“将来难以变更的部分”的原因,这个省事的定义简单地区分了软件系统中真的难以修改的部分和可以轻松修改的部分。但这个定义依然不免走进了盲区,因为开发者预先假设“变更是困难的”,这变成了一个自证式的预言。

几年前,一些富有创新精神的架构师用新的视角审视了“将来难以变更”的问题。使架构具有可变性会怎样呢句话说,如果易于改变是架构的基本原则,那么变更将不再困难。反过来,使架构具备演进能力会导致一组全新的行为出现,进而再次打破整个体系的平衡。

即使环境不改变,架构特征出现磨损该怎么办构师设计出架构,将其置于纷乱的现实世界,基于架构执行各项事务。架构师要如何保护他们定义的重要部分呢/p>

1.1.2 完成架构构建后,如何防止它逐渐退化

有一种不幸的退化叫作架构比特衰减,它在很多组织中均有发生。架构师选择特定的架构模式来满足业务需求及让系统具备某些能力,但这些特征常常意外地随着时间推移而退化。例如,架构师构建了一个包含顶部展现层、底部持久层和一些中间层的分层架构。负责 表功能的开发人员出于性能上的考虑经常会要求绕过中间层,直接从展现层访问持久层。架构师通过分层来隔离变化。而后开发人员绕过这些层,不仅增加了耦合,还使得分层变得毫无价值。

定义了那些重要的架构特征后,架构师如何保护这些特征不磨损呢案是添加演进能力作为新的架构特征,使其在系统演进时保护其他特征。比如,架构师追求架构设计的高伸缩性,但不希望在系统演进时削弱该特征。因此,演进能力是一种元特征和保护其他所有架构特征的架构封装器。

本书将阐明演进式架构的另一个作用,即它是一种为架构的重要特征提供保护的机制。我们探寻持续架构背后的理念。持续架构指构建架构的过程没有最终状态,它会随着软件开发体系的不断变化而演进,并保护重要的架构特征。我们不会尝试定义整个软件架构,因为已经存在很多定义了。我们通过引入时间变化作为头等架构元素来扩展当前的定义。

我们对演进式架构的定义如下。

演进式架构支持跨多个维度的引导性增量变更。

1.2 增量变更

增量变更描述了软件架构的两个方面:如何增量地构建软件和如何部署软件。

在开发阶段,允许小的增量变更的架构更易于演进,因为对于开发者来说,变更范围相对更小。对部署而言,增量变更指业务功能的模块化和解耦水平,以及它们是如何映射到架构中去的。示例如下。

假设有一个小工具商家 PenultimateWidgets,该商家采用微服务架构和一些现代工程实践运营着一个产品目录页面。该页面的一个功能是让用户给出小工具的星级评分。PenultimateWidgets 的其他一些业务也需要评分,比如客服代表、物流服务商评价等,所以这些业务共享星级评分服务。某天,该服务的开发团队发布了新版本,新版本允许用户给出半星评价(一个小而重要的升级)。其他需要评分的服务不需要强制升级,而可以逐渐地在合适的时候迁移到新版本。PenultimateWidgets 的 DevOps 实践采用了架构级别的监控,不仅监控各个服务,还监控服务与服务之间的路由。当运营人员观察到在给定时间内没有请求路由至特定服务时,他们自动将该服务从体系中移除。

这是一个在架构级别进行增量变更的例子:如有需要,原服务和新服务可以并存。团队可以在适当(不太忙或必要)的时候完成迁移,当所有迁移都完成时,旧版本的服务将会作为垃圾被自动回收。

增量变更的成功需要一些持续交付实践的配合。并不是任何情况都需要所有这些实践,但通常它们会一起发生。第 3 章将讨论实现增量变更的方法。

1.3 引导性变更

一旦架构师选择了重要的架构特征,他们会把变更引导进入架构,以保护这些重要特征。为此,我们借用演化计算中的一个概念:适应度函数。该函数是一种目标函数,用于计算潜在的解决方案与既定目标的差距。在演化计算中,适应度函数决定一个算法是否在持续提升。换句话说,随着每个算法变体的产生,基于设计者对算法“适应度”的定义,适应度函数决定每个变体的“适应程度”。

对于演进式架构,随着架构的演进,我们有着类似的需求。我们需要评估机制,来评估变化对架构重要特征的影响,并防止这些特征随着时间的推移而退化。适应度函数的隐喻涵盖多种机制,包括度量、测试和其他检验工具。我们采用这些机制来确保架构不会以不良方式变更。当架构师确定了需要保护的架构特征时,他们会定义一个或多个适应度函数来提供保护。

以往,架构往往要划出一部分作为管理活动,最近架构师才接受了通过架构实现变更的思想。架构适应度函数允许在组织需求和业务功能的上下文中制定决策,并为明晰且可测试的决策奠定了基础。演进式架构并不是毫无约束或不负责任的软件开发方式。相反,它可以在高速变迁的业务、严谨的系统需求和架构特征间找到平衡。适应度函数驱动架构设计决策,并引导架构变更适应业务和技术环境的变化。

第 2 章将详细介绍使用适应度函数指导架构演进。

1.4 多个架构维度

不存在单独的系统。世界是一个整体。如何划分系统边界取决于讨论的主题。

——Donella H. Meadows

古希腊的物理学通过固定点分析宇宙,最终发展成了经典力学。但是到了 20 世纪初,随着仪器越来越精密,现象越来越复杂,人们逐渐从经典力学转向相对论。科学家意识到之前被视为孤立的现象其实是相互影响的。自 20 世纪 90 年代起,受到启发的架构师越来越多地将软件架构视作多维的。持续交付也将运维纳入了软件架构的范畴。软件架构师往往关注技术架构,但那只是软件项目的维度之一。如果架构师想构建可演进的架构,就必须考虑系统中所有会受变化影响的部分。正如物理学所讲的,万物都是相关联的,架构师深知软件项目是多维的。

为了构建可以不断演进的软件系统,架构师不能只考虑技术架构。例如,如果项目包含一个关系型数据库,那么数据库实体之间的结构和关系也会随着时间的推移而不断变化。另外,架构师也不希望系统在演进过程中暴露安全漏洞。这些例子展示了架构的不同维度,它们通常在架构中以正交方式交织在一起。部分维度在常见的架构关注点范围之内(见表 1-1),但是架构维度的意义其实更广泛,它囊括了很多传统意义上技术架构范畴之外的东西。每个项目都有许多维度,架构师在考虑架构演进时必须要想到。下面是一些影响现代软件架构演进能力的常见维度。

  • 技术

    架构中的实现部分:框架、依赖的库和实现语言。

  • 数据

    数据库模式、表格布局、优化计划等。通常由数据库管理员(DBA)处理这类架构。

  • 安全

    定义安全策略、指导方针和指定工具来帮助发现缺陷。

  • 运维与系统

    关注架构如何映射到现有的物理或虚拟的技术设施中,包括服务器、机器集群、交换机、云等。

以上每个视角构成一个架构维度——为了支持特定视角而有意进行的划分。这里架构维度的概念涵盖了传统的架构特征和其他有助于构建软件系统的因素。随着问题和周遭环境的改变,我们想保护架构不磨损,每个维度都提供给我们一个审视架构的视角。

按照架构的维度思考,通过评估重要维度对变化的响应,架构师可以分析不同架构的演进能力。随着系统与互相冲突的问题(伸缩性、安全性、分布式、事务性等)关联得越来越紧密,架构师必须跟踪更多的维度。只有结合所有这些重要维度,思考系统将如何演进,才能构建出可以不断演进的系统。

项目的整个架构范围由软件需求和其他维度构成。当架构和整个体系随着时间的推移一起演进时,我们可以使用适应度函数来保护架构特征,如图 1-3 所示。

 

PenultimateWidgets 及其逆康威时刻

本书以 PenultimateWidgets 公司为例。它是排行倒数第二的小工具经销商,还是一家大型在线小工具(各种小商品)商家。这家公司正在更新其大部分 IT 基础设施,包括一些想暂时保留一段时间的遗留系统和正在迭代开发中的新战略系统。本书将重点介绍 PenultimateWidgets 所遇到的问题以及采取的解决方案。

他们的架构师首先观察了软件开发团队。旧的单体应用采用了分层架构,将展现、业务逻辑、持久化和运维分离开来。而他们的团队设置也和架构如出一辙:所有前端开发人员在一起工作,后端开发人员和数据库管理员也各自工作,运维则外包给了第三方。

当开发人员开始在架构(基于具有细粒度服务的微服务架构)上工作时,协调成本急剧增加。因为服务是围绕领域(例如用户结算)而不是技术架构来构建的,所以在变更单个领域时将需要各团队间进行大量的协调。

于是,PenultimateWidgets 采取了康威逆定律,建立了和服务范围相匹配的跨职能团队:每个服务团队包括服务负责人、几位开发人员、一位业务分析师、一位DBA、一位质量保障人员和一位运维人员。

本书多处提到了团队的影响,并会通过示例说明它带来的结果。

1.6 为何演进

对于演进式架构,一个常见的问题是关于其名称的:为什么叫作演进式架构而不是别的如增量式持续式敏捷式响应式应急式,等等。这些术语都不够准确达意。这里所说的演进式架构包含了两个关键特征:增量和引导。

持续式敏捷式应急式都表达了随时间不断变化的概念,这确实是演进式架构的关键特征,但是这些术语都没能准确地表达出架构将如何变化,或者说期望的架构最终是什么样子的。虽然这些术语都隐含着环境变化,但是都没能涵盖架构应有的样子。而在演进式架构的定义中,引导的含义反映了我们想实现的架构,即我们的最终目标。

相比可适应这个词,我们倾向于演进式,因为我们对经历根本性演变的架构感兴趣,而不是那些经历了修修补补后变得越来越难以理解、复杂问题频发的架构。适应意味着解决方案不求优雅或长久,只要能找到方法使系统运作就行。为了构建能实实在在演进的架构,架构师必须支持真正的变化,而不是权宜之计的考虑。回到我们的生物学隐喻,演进是这样一个过程:建立一个适用的并能在其所处的不断变化的环境中持续运行的系统。系统可能存在个别的适应性,但是架构师应该关心整体可演进的系统。

1.7 小结

演进式架构主要由三方面构成:增量变化、适应度函数和适当的耦合。本书余下的部分将分别讨论它们,然后再将它们结合起来,帮助我们构建和维护支持不断变化的架构。

演进式架构

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年8月2日
下一篇 2019年8月2日

相关推荐