《架构师修炼之路》——②对架构的基本认识
1、什么是架构
在软件领域,经常会听到“架构”一词,如:MVC架构、微服务架构等,虽然常见,但具体的指的是什么呢?
先来看IEEE关于架构的定义:
the fundamental organization of a system, embodied in its components, their relationships to each other and the environment, and the principles governing its design and evolution --ANSI/IEEE
一个系统的基础组织形式,体现为其组件、关系(组件间及其与外部环境间)、指导系统设计和演进的原则。 通过图形化的形式示意如下:

这是一个非常简洁、清晰的定义,明确了系统架构中的关键要素,即:组件、关系、设计和演进原则,同时也突出了环境要素。
架构(Architecture)这一概念的来源:
架构(Architecture)最初用在建筑领域,原指建筑物整体结构与空间关系的规划。其词源可追溯至拉丁语“Architectura”,源自希腊语“Arkitekton”,意为“主建筑师”或“建筑师”。这一术语最初用于描述建筑物的设计、建造及其组织方式,强调结构稳定性、功能性和美学价值的综合考量。

在软件领域,引入架构的概念用于表示软件系统的骨架,并将架构设计作为描绘整个系统的蓝图。架构设计与代码实现不同,关注的是”如何组织代码”而非”怎么编写代码”。现代软件架构通过抽象描述系统组件和交互方式,指导大型软件系统的开发,其核心仍延续了建筑学中关于结构规划与系统优化的思想。

在其他领域,也有类似的概念,如“组织架构”、“信息架构”等。
尽管软件架构与建筑架构是类似的概念,但是在设计的出发点上却有明显不同:
建筑架构:面向静态设计,一是建筑物本身是处于静止的状态,而不是运动的状态;二是通常情况下用户需求是稳定的,即建筑物在后期使用过程中很少发生变化。好的建筑架构,应该具备稳定、安全、舒适等特征。
软件架构:面向动态设计,一是软件系统在使用过程中是运行的,需要考虑性能等属性,二是软件系统会随着用户需求进行演进。一般说来,多数的软件系统上线后都需要应对变化,例如增加或修改功能,扩展系统规模等,几乎没有一成不变的系统。因此软件架构需要能够适应变化,并且在变化过程中还要维持既有功能的稳定。好的软件架构,需要具备灵活、高效、稳定等特征。
因此,软件架构与建筑架构对于结构规划与系统优化的目标是不一样的。
2、架构的演进历程
早期时候,软件架构确实并不是什么热门话题,因为那时的程序都很小,功能简单,管理一个小型系统所需的架构设计远没有那么复杂。程序员通常使用一些简单的流程图来描述程序的结构。
随着计算机硬件技术的快速进步,软件的规模也逐渐变大,应用场景和需求越来越复杂,架构的重要性才逐步被认识到。从单体架构到微服务架构及无服务架构,软件架构经历了一个不断追求“分治”和“解耦”的过程。

1)单体架构(Monolithic Architecture)
产生背景:早期计算机资源有限,软件规模较小,业务逻辑简单。
架构特点:所有功能模块(UI、业务逻辑、数据访问)打包为一个单一应用程序,通常以单一进程运行。
主要技术栈:Java EE、LAMP(Linux+Apache+MySQL+PHP)、Spring MVC、ASP.NET。
优点:开发部署简单,适合小型项目,性能较高(模块间调用无网络开销)。
局限性:代码耦合度高,扩展性差,维护困难(修改需整体部署)。
2)分层架构(Layered Architecture)
产生背景:随着软件复杂度上升,需分离关注点以提高可维护性。
架构特点:按功能横向分层(如表现层、业务层、数据层),层间通过接口通信。
主要技术栈:MVC框架(Spring MVC、Ruby on Rails)、三层架构(前端+后端+数据库)。
优点:职责分离,便于团队协作,可替换单层技术(如更换数据库)。
局限性:层间可能产生性能瓶颈,跨层调用易导致紧耦合。
3)面向服务架构(SOA, Service-Oriented Architecture)
产生背景:企业需整合异构系统(如ERP、CRM),实现跨部门服务复用。
架构特点:将功能拆分为独立服务,通过标准协议(如SOAP、ESB)通信,强调服务可重用性。
主要技术栈:SOAP/WSDL、Apache CXF、IBM WebSphere ESB。
优点:服务可跨系统复用,支持异构技术栈集成。
局限性:ESB易成单点故障,协议笨重(XML解析开销大),部署复杂。
4)微服务架构(Microservices Architecture)
产生背景:2010年后,云计算和DevOps兴起,需快速迭代和独立扩展。
架构特点:服务粒度更小(将系统按业务域拆成独立运行的小服务,如订单服务、支付服务),独立部署,轻量通信(如REST/gRPC)。
主要技术栈:Spring Boot、Docker、Kubernetes、Istio、Prometheus。
优点:高内聚低耦合,技术栈灵活(每服务可用不同语言),弹性扩展。
局限性:分布式系统复杂度高(需处理网络延迟、一致性),运维成本高。
5)事件驱动架构(EDA, Event-Driven Architecture)
产生背景:与微服务同期发展(微服务架构中采用消息驱动的一种特例),适用于实时数据处理和异步场景。
架构特点:微服务之间通过事件(消息)触发服务,松耦合,支持最终一致性。
技术栈举例:Kafka、RabbitMQ、AWS EventBridge。
优点:高吞吐异步处理,易扩展消费者服务。
局限性:事件流调试困难,需额外处理消息堆积。
6)无服务器架构(Serverless Architecture)
产生背景:2015年后,云计算成熟,追求极致弹性与成本优化。
架构特点:开发者聚焦业务代码,基础设施由云平台托管(如FaaS、BaaS)。
主要技术栈:AWS Lambda、Azure Functions、Google Cloud Run、阿里云Function Compute、华为云Function Graph。
优点:按需计费,零运维成本,自动扩缩容。
局限性:冷启动延迟, vendor锁定,不适合长任务。
架构演进的主要动力是解耦与弹性。现代架构的发展趋势是混合使用多种架构风格和架构模式,云原生技术亦成为标配 (K8s、Service Mesh)。
上述单体架构、分层架构、微服务架构等概念,就是讲的“架构风格”,而“架构模式”则是容易和架构风格相混淆的另一个概念。二者的主要区别是:
架构风格: 组件和组件关系是系统架构的重要组成部分,其从宏观上表述了系统的结构组成。架构设计的核心任务之一是为系统选择合适的架构风格。架构风格是软件架构设计的 “模板”或“套路”,它定义了组件、组件间交互方式及原则,解决某类通用场景下的设计问题。
架构模式: 架构模式是针对特定问题的“解决方案”,是风格在具体场景下的落地(如微服务中的API网关模式、分层中的Repository模式)。在同一架构风格上下文内可以应用一或多种架构模式。
简单说,风格是“战略”,回答“整体用什么思路设计”;模式是“战术”,解决“某个具体环节怎么实现”。比如选择“微服务”风格后,用“服务注册发现”模式解决服务间找到彼此的问题。
3、架构设计是否真的有必要?
在一些公司或项目中,开发一个软件系统,其主要步骤通常就是需求分析、画流程图、设计数据库,然后编码实现、测试验证、部署上线,其中并没有架构设计的环节,并且最终也基本都能成功上线。换句话说,架构设计的环节不是必须的。
但我认为并非如此,在项目中进行架构设计非常有必要。Why?因为:重要、值得!做架构设计,虽然会多一点投入,但收益高(质量更好,成本更低,效率更高);不做,后续阶段可能付出更多代价!
建筑的架构是什么?它不只是一张建筑效果图,也不是那本厚厚的施工图纸。这些都只是架构的表达形式。房子的真正架构,是那些在动工之前就经过深思熟虑而确定下来的最核心、最基础、且一旦做出就极难更改的决策的集合 。同理,软件架构所处的地位也类似。例如:
- 建筑的地基的类型和深度,决定了房子能盖多高,抗震等级如何;软件系统的基础技术栈选型、核心数据模型和部署环境,决定了能承载的系统规模、性能和可靠性。选错了,推倒重来的成本是毁灭性的。
- 建筑的承重墙的位置和结构,决定了房子的空间布局和未来的改造可能性;软件系统中的核心组件划分,服务边界和关键交互协议,决定了未来的演进方式。一旦确定,想移动一堵“承重墙”,几乎等于重建。
- 建筑的水电煤管网的整体布局:决定了房子的生命线能否高效、安全、稳定地运行;软件系统中的数据流、通信机制、以及关键的非功能性设计,决定了系统质量属性(如高可用、高并发)能否得到满足。
在我看来,架构设计的主要价值包括:
- 支持需求实现:确保系统能够承载功能需求和非功能需求(如性能、可靠可用、可伸缩性、安全性),消除系统性的风险。
- 管理复杂性:通过抽象和解耦,减小理解难度,使系统更易于构建和维护。
- 指导实现,促进沟通:为不同干系人(特性设计、开发、测试、管理者、客户)提供各个需求特性设计的共同基准。
- 支持维护:为系统维护提供蓝图。按图索骥,不至于无从下手;保持秩序,不至于越改越乱。
- 支持演进:隔离变化,使系统能够适应未来变化并保持相对稳定。
某些看似没有做架构设计的项目,其实是在做系统特性设计的时候将架构元素也一并考虑进去了,只是没有开展专项的架构设计。(但这种方式并不推荐,一是缺乏系统性的思考,可能存在遗漏;二是架构知识分散,或停留在设计人员大脑中,不利于指导团队开发和长期的知识沉淀)
下面再通过三个真实的架构案例来感受一下软件架构的重要性:
- 失控的"意大利面代码"
某创业公司搭建一个小型外卖系统时为了赶进度,直接在控制器里写数据库查询,在视图层处理业务逻辑。上线几个月后,为支持一个简单的促销活动,需要同时修改多个文件,各部分的开发人员因为"谁先改"的问题在会议室吵了半天仍没有结果。这就是没有架构带来的问题之一——代码像意大利面一样缠成一团。 - 会"生长"的支付系统
某支付平台早期架构师设计了一个"插件式"支付网关,当需要新接入一种支付渠道时工程师只需按照接口规范写个新的插件即可,例如支持比特币支付,不到一周就完成上线。这就是架构的魔力——提前做好扩展点,新需求就像插USB接口一样简单。 - 被流量压垮的"完美代码"
某公司软件团队用最新技术为系统写了一套优雅的代码,但没考虑服务弹性伸缩、数据库分库分表。发布会当天10万用户涌入,所有请求卡在单点数据库,CEO在台上演讲时,出现系统卡住的尴尬情况,运维人员想紧急增加资源进行系统扩容,但是被告知需要先做一些改造,且短期内搞不定。这告诉我们:除了代码的优雅,系统主要还得考虑整体的性能和扩展性,就像造桥那样既要美观更要考虑车流量。
4、架构设计的本质——决策和平衡
软件架构设计是对一个系统在特定场景下,为了满足一系列业务目标,而做出的一系列重大设计决策的集合,包括选择哪种风格的架构,以及基于这种风格如何进行结构规划和系统优化、会应用哪些架构模式,这些都是架构决策要解决的问题。这些决策深刻地影响着系统的结构、行为、质量属性以及长期的演化能力。
三个关键点:
- 架构设计的核心不是代码,也不是文档,而是高质量的决策。文档只是载体。
- 这些决策不是在真空中产生的,它们受到业务目标、时间、成本、团队技能等现实因素的制约。
- 这些决策是影响深刻的,如同战争决策,一旦开打便会影响整个战局的走向,且往往不可逆。
架构师的核心目标就是基于特定的场景作出满足业务目标、且影响深远的重大架构决策,而其中的利益相关者包括客户及产品经理、项目经理、开发和测试、运行维护等方方面面,因此每一个重大决策都是在“利益相关者”的诉求中寻找平衡。
一个只考虑业务方诉求的建筑师,可能会设计出美轮美奂的房子,但成本可能会严重超标,导致项目破产。一个只考虑施工方便的建筑师,可能会偏离商业目标,只是比较容易造出房子,给未来埋下隐患。
同理,一个只追求技术酷炫的软件架构师,可能会交付一个过度设计、成本高昂、极难维护的“精密的”系统。一个只追求上线速度快的架构师,可能会交付一个短期能用但长期来看是摇摇欲坠、无法修改和扩展的“纸糊的”系统。

作为一名架构师,就需要面对如此种种矛盾。他的核心职责,就是识别并理解所有利益相关者的诉求(这些诉求往往被包装成“需求”或“指标”),然后通过一系列深思熟虑的权衡,产出恰如其分的架构决策,在这些看似相互冲突的目标之间达成一种精妙的平衡。
因此,架构设计工作本质上是一项沟通、协调与决策的工作。架构师需要用业务方能听懂的语言解释技术决策的商业影响,用开发团队能理解的蓝图指导具体的实现,用运维团队能接受的方案保障系统的稳定。决策背后的“为什么”,远比决策本身“是什么”更重要。这个“为什么”,就是向所有利益相关者解释你如何平衡他们利益的理由。
5、架构决策的依据是什么?
如何科学、系统的进行架构决策?这就需要了解架构的驱动因素,它们是决策的依据。其实上文中已陆续提及过许多因素,这里我们将其归纳为三个方面:功能需求、质量属性、约束。

- 功能需求:
系统需实现的具体功能,即系统在运行过程中接收外部激励时所做出的行为或响应,它们与用户业务目标相关。系统中的核心功能和稳定性高的功能需求,会影响架构设计。 - 质量属性:
系统需满足的各种非功能性要求,它们从根本上决定系统架构。包括:- 开发期——易实现性、并行开发、可测试性等(影响开发效率)
- 运行期——如性能、可靠性、可伸缩性、安全性等(影响用户业务目标和体验)
- 维护期——如可扩展性、可观测性、可维护性等(影响系统稳定和后续演进)
为什么从根本上决定系统架构的因素是质量属性,而不是功能需求呢?
举个例子:假设要开发一个售票系统,包括用户管理,票务管理,查询与预订,订单管理,系统设置等功能,要实现这些功能需求,采用单体架构或分层架构、微服务架构都可以;但是如果要求支持高并发和弹性伸缩,就不能采用单体架构;如果用户数量有限,且要求程序小巧精简、资源开销极低、用户需要经常在单机上运行,则不适合采用微服务架构。因此可以看出,质量属性才是系统架构的决定性因素。
- 约束
设计中必须遵循的限制条件,如技术规范、法律法规、组织架构调整等,架构设计时必须要了解这些约束限制。可以近似的认为,它们对系统架构具有“否决权”。
6、模块、组件和微服务的概念
在软件架构设计中,模块(Module) 和 组件(Component) 是两个核心概念,二者均用于拆解复杂系统,但在侧重点和应用场景上又存在明确区别。另外,在微服务架构中系统被拆解为微服务(Microservice),微服务与前二者又是什么关系?
三者的关系如下图所示:

-
模块(Module)
模块是以功能逻辑划分的代码单元,是系统内部的“逻辑组织单位”。
核心目标:把系统的内部实现按照“高内聚、低耦合”的逻辑拆分,解决“代码怎么组织”的问题,主要是面向开发者。
典型特征:- 边界由“功能职责”界定(如“用户认证模块”“订单计算模块”);
- 通常是代码级别的概念(对应源码目录、包结构,如Java的 package 、Python的模块文件);
- 侧重“内部逻辑的封装”,对外暴露有限的接口(如函数、类)供其他模块调用。
-
组件(Component)
组件是以可复用、可独立部署为目标的“物理/部署单元”,是系统中可替换、可组合的独立部分。
核心目标:通过对系统拆分,提升复用性和部署灵活性(如微服务、中间件组件)。解决“系统怎么装配、部署”的问题,面向架构师和运维
典型特征:- 边界由“物理存在”界定(如一个JAR包、一个Docker容器、一个独立服务);
- 是更高层级的概念(可包含多个模块,如“支付组件”可能包含“支付接口模块”“订单对账模块”);
- 侧重“外部交互的标准化”,通常通过统一接口(如REST、RPC)与其他组件通信,具备“即插即用”的特性。
模块与组件的区别:
| 对比维度 | 模块(Module) | 组件(Component) |
|---|---|---|
| 划分依据 | 功能逻辑(“做什么”) | 物理部署/复用性(“是什么、怎么用”) |
| 粒度层级 | 代码级(细粒度) | 部署级(粗粒度,可包含模块) |
| 核心目标 | 逻辑解耦、方便开发维护 | 独立复用、灵活部署、系统装配 |
| 存在形式 | 源码包、类库、函数集合 | JAR/WAR包、容器、独立服务、插件 |
| 依赖关系 | 通常是编译时依赖(代码引用) | 通常是运行时依赖(接口调用) |
- 微服务(Microservice)
在微服务架构中,将软件系统拆分为多个“微小的、独立部署的服务单元”,称之为“微服务”。每个微服务聚焦单一业务能力,通过轻量级通信协议(如HTTP/REST)协同工作。微服务是组件的一种特定形态,是“特殊与一般”的关系。
核心目标:解决“大型系统的弹性、敏捷、可扩展”问题。
典型特征:“去中心化”,即每个微服务独立开发、测试、部署、扩展,拥有自己的数据库(数据去中心化)和技术栈(技术去中心化)。
微服务与组件的区别:
- 微服务必然是组件:微服务满足组件“独立部署、可复用、有明确接口”的核心特征(如“支付微服务”就是一个可独立部署、供订单服务调用的组件)。
- 组件不一定是微服务:组件的范围更宽泛,除了微服务,还包括传统单体应用中的独立模块打包(如Jar包)、前端组件(如Vue组件)、中间件组件(如Redis客户端组件)等。
7、常见的架构设计方法
上面说了这么多,但对于具体如何开展设计,可能大家还是觉得比较抽象。要进行架构设计,还需要一套科学的方法论,基于方法论的指导来开展设计。
方法论是业界比较成熟的优秀实践,也是行业人员交流的通行语言。基于方法论逐步开展设计,可以引导架构师进行全面的思考、避免遗漏;同时,将架构设计的结果采用统一的语言进行表述,可以有效地表示、交流和记录架构。
架构设计的方法比较多,下面列举两种常用的方法:
- 4+1视图:逻辑视图、开发视图、部署视图、运行视图 + 用例视图。
- C4模型:语境图、容器图、组件图、类图(或其他代码级图),层次化描述。
下一篇将对4+1视图法进行展开介绍。
小结
- 架构的定义:一个系统的基础组织形式,体现为其组件、关系(组件间及其与外部环境间)、指导系统设计和演进的原则。
- 软件架构不断追求“分治”和“解耦”,经历了从单体架构到分层架构、面向服务架构、微服务架构以及无服务架构的演进过程。
- 开展架构设计非常有必要。做了,收益高;不做,代价大。
- 软件架构设计的本质为决策和平衡。
- 架构决策过程需要以系统的功能、质量属性和约束为依据,质量属性是决定因素。
- 架构设计中的模块和组件都是对系统拆解后的组成单元,模块面向代码复用,组件面向独立部署和维护;微服务是一种特殊类型的组件。
- 架构设计方法是架构设计的工具和载体,引导全面思考,是业内通行的表述语言。
