本文内容整理来源马丁福勒(martinfowler):www.martinfowler.com/architectur...
1. 什么是架构
软件架构没有绝对客观的定义,传统定义如"系统的基本组织"或"早期必须做出的设计决策"都存在主观性和局限性。
架构不是由"高层"或"基础"组件决定的,架构是一种社会建构,依赖于专家开发者之间的共同理解,而非某个权威的蓝图。
架构 = 团队共识中"重要的事" ------ 不是技术本身决定什么是架构,而是开发团队认为哪些部分重要。

架构关乎重要的东西------无论那是什么。真正定义架构的,是"难以改变"的东西;一旦某件事变得容易修改,它就不再是架构问题
架构的本质在于识别和维护"重要性":软件不像建筑那样受物理定律的限制。它受限于想象力、设计和组织方式。简而言之,它受限于人的特性,而非世界的特性。
软件架构 = 团队共识中被认定为"重要"的设计要素,及其持续治理
2. 为什么架构如此重要
软件架构对用户不可见,但至关重要:用户虽感知不到架构好坏,但糟糕的架构会迅速积累"cruft"(技术杂质),使代码难以理解与修改。
cruft 的危害:导致开发效率下降、新功能交付变慢、缺陷增多,最终拖累产品演进。

与"高质量=高成本"的常识不同,高内部质量(如良好架构)反而加速开发,因为减少了阻碍。
虽然初期可快速交付,但 cruft(常译为'技术杂质'或'代码腐化',指因忽视内部质量而积累的缺陷) 的负面影响来得极快

2.1. 技术债务
软件系统容易积累杂质 ------内部质量的缺陷,使得进一步修改和扩展系统比理想情况下更困难。
技术债务是一个隐喻,由沃德·坎宁安提出,用来描述如何思考处理这些垃圾,把它当作一笔金融债务来看待。增加新功能所需的额外努力就是偿还债务的利息

2.2. 高质量不等于更高成本
提升内部质量(偿还本金)虽短期耗时,但长期显著降低新功能开发成本。
误区:认为"先做功能,质量以后再说"能加速交付------实际上 cruft 会迅速拖慢开发速度,几周内就显现负面影响(远快于预期)
审慎债务:明知有代价,但为紧急需求主动承担,并计划后续偿还。
鲁莽债务:因忽视质量或能力不足而积累,无偿还计划,最终导致系统难以维护。

技术债务不是借口,而是决策框架:短期可借债,但必须主动管理;长期看,持续偿还"本金"(提升质量)是唯一可持续的高效开发之道
2.3. 内部质量至关重要
客户无法感知代码架构好坏,但内部质量直接决定团队添加新功能的速度与稳定性。牺牲质量看似加速初期交付,但几周内就会被 cruft 拖垮,远快于多数人预期
软件开发本质是探索:需求模糊、技术演进快,架构总是在"事后才看清"。优秀团队的差别:
- 不是不产 cruft,而是持续清理(重构、自动化测试、CI);
- 像厨房做饭后立即清洁------防止污垢干涸变难处理。
软件的内部质量不是奢侈品,而是效率引擎------忽视它,短期看似省时,实则迅速陷入泥潭;投资它,虽有微小前期成本,却换来长期低成本、高速度、高竞争力。
3. 微服务
3.1. 微服务前置条件
微服务虽带来开发上的模块化优势,但显著增加运维复杂度;若缺乏必要的工程与运维基础能力(如自动化、监控、DevOps协作等),不应贸然采用微服务架构。
微服务不是"开箱即用"的解决方案,而是有门槛的架构选择------能力不足时,拆分会带来更大风险

从管理一个单体应用变为维护一个分布式服务生态系统。采用微服务前必须具备三项基础能力:
快速配置(Rapid Provisioning):短时内能启动新服务实例,依赖高度自动化。
基础监控(Basic Monitoring):能快速发现技术与业务异常,并支持快速回滚。
快速部署(Rapid Deployment):通过部署流水线在数小时内完成测试/生产发布,逐步实现全自动化。
这些能力要求组织文化转型------拥抱 DevOps:开发与运维必须紧密协作,共同应对故障、进行根因分析和持续改进。建议渐进式演进:
- 从少量微服务开始,在生产中验证流程与协作;
- 先构建能力,再扩大规模;切勿在不具备基础能力时盲目拆分。
这些能力对单体系统同样重要:自动化、监控、持续交付应是所有现代软件团队的高优先级目标。大规模微服务需要更高阶能力:
- 跨服务的分布式追踪;
- 全面的持续交付(Continuous Delivery);
- 以产品为中心的团队结构;
- 支持多仓库、多语言的开发环境;
- 未来可能形成微服务成熟度模型,指导组织演进。
微服务的成功不取决于技术本身,而取决于组织是否具备自动化、监控、部署和 DevOps 协作等基础工程能力------没有这些,微服务只会放大混乱
3.2. 微服务介绍
3.2.1. 微服务的核心定义
微服务架构风格是一种将单个应用开发为一组小型服务的方法,每个服务各自运行于自己的进程中,并通过轻量级机制(通常是 HTTP 资源 API)进行通信。
这些服务围绕业务能力构建,并可由全自动部署流水线独立部署。 这些服务仅有最低限度的集中管理 ,这些服务可能用不同的编程语言编写,并使用不同的数据存储技术。

关键特性:
- 通过轻量级通信机制(如 HTTP API)交互;
- 围绕业务能力组织;
- 可独立部署,依赖全自动化的部署流程;
- 去中心化治理:允许使用不同语言、数据库和技术栈;
- 最小化集中管理。
3.2.2. 微服务的典型特征
通过服务实现组件化
- 组件 = 独立可替换/升级的单元;
- 服务(进程外)优于库(进程内),因支持独立部署。
围绕业务能力组织
- 团队按业务领域划分(如"订单"、"用户"),而非技术层;
- 团队全栈负责(前端、后端、DB、运维)。
产品思维,非项目思维
- "You build it, you run it":团队对服务全生命周期负责;
- 建立开发者与用户的直接反馈闭环。
智能端点 + 哑管道(Smart Endpoints & Dumb Pipes)
- 业务逻辑在服务内部(智能端点);
- 通信机制极简(HTTP/REST、轻量消息),避免 ESB 式复杂中间件。
去中心化治理
- 不强制统一技术栈;
- 推广内部开源、共享工具库(如 Netflix OSS);
- 标准来自实践(如 HTTP),而非纸上规范。
去中心化数据管理
- 每个服务拥有私有数据库(Polyglot Persistence);
- 放弃分布式事务,采用最终一致性 + 补偿机制;
- 明确有界上下文(Bounded Context)隔离语义差异。
基础设施自动化 + 故障设计
- 依赖 CI/CD、容器化、云平台实现高效部署;
- 默认服务会失败:用断路器、超时、监控、混沌工程(如 Simian Army)提升韧性;
- 实时监控业务 & 技术指标(语义监控)。
3.2.3. 微服务的优势 vs. 代价
| 优势 | 代价/挑战 |
|---|---|
| ✅ 强模块边界:提升大型团队协作效率 | ❌ 分布式复杂性:远程调用慢、易失败 |
| ✅ 独立部署:降低变更风险,加快发布 | ❌ 最终一致性:难以保证强一致性,需业务层处理 |
| ✅ 技术多样性:自由选型语言与存储 | ❌ 运维复杂度高:需成熟 DevOps 能力支撑 |
| 挑战 | 说明 |
|---|---|
| 运维复杂度剧增 | 服务发现、日志聚合、分布式追踪、监控告警等需强大 DevOps 支撑 |
| 分布式系统固有问题 | 网络延迟、部分失败、数据一致性、调试困难 |
| 重构成本高 | 跨服务移动代码比单体内重构困难得多 |
| 团队能力门槛高 | 需要成熟工程文化、自动化能力和跨职能协作 |
| 可能"转移复杂度" | 若服务划分不当,复杂性从内部转为混乱的服务间耦合 |
3.2.4. 微服务选择
微服务不是默认选择,大多数场景下,单体架构更合适;微服务仅在具备足够工程能力、团队规模和业务复杂度时才值得采用;切勿为了"时髦"而用微服务------它解决的是特定问题,也带来新的问题。
核心建议:先夯实自动化、监控、CI/CD 和 DevOps 基础,再考虑是否"够高"使用微服务。

微服务是一种以业务为中心、高度自治但运维复杂的架构风格------它强大,但只适合"准备好了"的团队。
3.3. 单体架构
使用微服务时,必须处理自动化部署、监控、故障处理、最终一致性以及分布式系统带来的其他因素。虽然有众所周知的应对方法,但这需要额外努力,理论上软件开发领域似乎没有人有大量空闲时间。

3.3.1. 单体架构不等于落后
良好模块化的单体完全可以支持持续交付;理论上单体可保持清晰边界,但实践中容易退化为"大泥球",需强工程纪律。
不要因潮流而拆分,而应因真实痛点而拆分。能用单体就用单体。保持简单,延迟拆分。只有在单体真正成为瓶颈时,才转向微服务。
微服务是解药,也是毒药------只在系统复杂到单体无法承受时才值得服用。过早采用微服务会带来显著成本与风险:需处理分布式系统难题(如部署自动化、监控、容错、最终一致性等
3.3.2. 单体优先
避免过早优化(YAGNI 原则)
- 新项目最大的风险不是"无法扩展",而是"没人用"。
- 单体开发更快、反馈周期短,利于快速验证产品价值
微服务成败关键在于服务边界是否合理(即 DDD 中的"有界上下文")。即使专家也很难在项目初期划对边界;而在单体中重构模块成本低,可逐步探索正确切分点。

先跑起来,再跑得漂亮------用单体快速验证价值,用微服务应对成长之痛。
3.4. 单体架构和微服务架构图
| 问题 | 单体架构 | 微服务架构 |
|---|---|---|
| 部署 | 全量重建部署,即使小改动 | 仅部署变更服务 |
| 扩展 | 整体横向扩展,资源浪费 | 按需扩展高负载服务 |
| 技术演进 | 锁定单一技术栈 | 各服务自由选型(Polyglot) |
| 团队协作 | 跨职能割裂(UI/DB/后端),沟通成本高 | 跨功能团队负责端到端业务能力(康威定律) |
| 模块化 | 随时间退化,逻辑耦合严重 | 服务即模块边界,强制解耦 |
微服务在大型、复杂、快速演进的企业应用中展现出显著优势;但其成功高度依赖团队能力、自动化水平和架构纪律;没有"未来架构",只有"适合当前上下文的架构" ------需基于不完美信息做务实决策。
"微服务不是目标,而是应对复杂性的手段。"

4. 如何将单体拆解为微服务
拆分单体是为了加速业务价值交付、提升团队自治、降低变更成本,而非追求技术时髦

4.1. 关键原则
从简单边缘能力热身(Warm Up)
- 先拆低耦合、无数据依赖、改动影响小的功能(如认证、客户档案)。
- 目的:验证 CI/CD、监控、API 管理等微服务基础设施,培养团队能力。
最小化对单体的反向依赖(Minimize Backward Dependency)
- 新服务不应调用单体内部逻辑或数据,否则丧失独立发布优势。
- 若必须调用,通过防腐层(Anti-Corruption Layer) 隔离单体概念,暴露清晰 API。
优先拆解"粘性能力"(Split Sticky Capabilities Early)
- 识别单体中高度耦合的"胶水"模块(如 Web Session),它阻碍其他功能解耦。
- 不要直接将其变成服务,而应解构为多个清晰的领域概念(如愿望清单、支付偏好),再逐个拆出。
纵向解耦 + 数据先行(Decouple Vertically & Release Data Early)
- 微服务 ≠ 只拆代码,必须连同其专属数据一起迁移。
- 避免"只拆前端或后端"的反模式------不解耦数据 = 不是微服务。
- 采用如 Stripe 的四阶段数据迁移策略,确保平滑过渡。
优先拆解高价值、高频变更的能力(Business-Driven Prioritization)
- 聚焦业务差异化强、迭代频繁的功能(如个性化推荐、促销引擎)。
- 通过代码提交分析(CodeScene)+ 产品路线图,识别"最值得拆"的模块。
重写能力,而非搬运代码(Rewrite Capability, Not Code)
- 不要因情感依恋而复用老旧、高毒性代码。
- 除非是高 IP、低毒性的核心逻辑,否则建议重写新服务 + 退役旧代码。
- 利用机会:简化业务流程、更新技术栈、澄清领域模型。
先宏观,再微观(Go Macro First, Then Micro)
- 初期拆出围绕完整业务场景的"宏服务"(如"购买"包含购物车+结账)。
- 待团队运维能力成熟后,再按需细化为更小服务。
- 避免过早拆成大量贫血 CRUD 服务,导致分布式复杂性失控。
不要幻想"一次性消灭单体",而要通过持续、小步、可回滚的演进逐步替换。架构演进 = 组织能力演进。拆分节奏应匹配团队的工程成熟度。始终问:这次拆分是否让系统更接近"快速、安全、独立交付业务价值"的目标。
解耦不是技术切割,而是业务能力的重新封装;迁移不是代码搬家,而是架构与组织的协同进化
5. Serverless 架构
无服务器架构是集成第三方"后端即服务"(BaaS)服务和/或包含在托管的临时容器中运行的定制代码的应用设计,运行在"功能即服务"(FaaS)平台上。
通过采用这些理念及相关理念,如单页应用,此类架构大大减少了对传统始终在线服务器组件的需求。
5.1. 什么是 Serverless
Serverless 并非"没有服务器",而是指开发者无需管理底层服务器基础设施,将运维责任外包给云厂商。
- BaaS(Backend as a Service)
-
- 使用第三方托管的后端服务(如 Firebase、Auth0),替代自研服务器逻辑。
- 常用于富客户端应用(如单页 Web 应用、移动 App)。
- FaaS(Functions as a Service)
-
- 开发者编写函数代码,由平台按事件触发、自动扩缩容、按执行付费(如 AWS Lambda)。
- 函数是无状态、短暂、事件驱动的计算单元

5.2. 核心优势
| 优势 | 说明 |
|---|---|
| 极致弹性 & 按需付费 | 自动扩缩容,仅对实际执行时间计费(如 AWS Lambda 精确到 100ms)。 → 极大降低低频/突发流量场景成本。 |
| 免运维(No-Server Management) | 无需管理服务器、容器、集群;部署只需上传代码。 |
| 加速创新与实验 | 新功能可快速上线验证(如监听 Kinesis 流的 Lambda 函数几分钟内部署)。 |
| 资源高效 & 更环保 | 云厂商聚合多租户负载,提升硬件利用率,减少能源浪费。 |
5.3. 主要挑战与限制
| 挑战 | 说明 |
|---|---|
| 冷启动延迟 | 首次调用或闲置后重启时存在延迟(毫秒至秒级),影响实时性要求高的场景。 |
| 状态管理受限 | 函数实例无持久本地状态,需依赖外部存储(如 S3、Redis、DB)。 |
| 执行时长限制 | 主流平台限制单次执行时间(如 AWS Lambda 最长 15 分钟)。 |
| 调试与监控困难 | 分布式追踪、日志聚合、性能分析工具尚不成熟。 |
| 供应商锁定(Vendor Lock-in) | 各家 FaaS 接口、生态(如触发器、API 网关)差异大,迁移成本高。 |
| 安全与权限复杂度 | 大量函数需精细配置 IAM 策略,易出错。 |
5.4. 总结
- Serverless ≠ NoOps
运维从"服务器管理"转向"应用生命周期管理"(监控、安全、部署等),复杂度转移而非消失。 - 与 PaaS / 容器的区别
-
- PaaS:仍需考虑扩缩容单位(如 Dynos);FaaS:以请求为单位自动伸缩。
- 容器:需管理集群;FaaS:完全托管,粒度更细。
试用场景:
- 适合:事件驱动、轻量级、突发流量、快速原型、成本敏感型应用。
- 慎用:长时任务、强状态依赖、超低延迟、复杂事务、已有庞大单体系统。
- 前提能力:需具备自动化部署、可观测性、云原生安全实践。
💡 核心思想:Serverless 的本质是将基础设施复杂度外包,换取开发敏捷性与成本效率,但需接受其约束并重构应用设计。
Serverless 不是万能药,而是特定场景下的高效杠杆------用架构约束换弹性与速度,用厂商依赖换运维简化。
6. 微前端 Micro Frontends
6.1. 背景
许多公司在后端采用微服务架构后,前端仍被庞大的单体(Monolith)代码库所困。这导致难以集成新技术、扩展开发团队、快速迭代和维护。
微前端是一种将大型前端单体拆解为多个小型、独立、可单独开发、测试和部署的前端应用的架构风格。这些独立应用最终组合成一个对用户而言无缝的整体产品。

6.2. 主要优势
- 渐进式升级:无需重写整个应用,可以逐步替换旧模块,降低风险。
- 简单、解耦的代码库:每个微前端代码量小、内聚性高,减少了意外耦合。
- 独立部署:每个微前端拥有自己的CI/CD流水线,可随时发布,不受其他部分影响。
- 自治团队:团队围绕业务功能(垂直切片)而非技术栈(水平切片)组建,能端到端地负责一个功能,提升效率和响应速度。
每个微前端都应拥有自己的持续交付流水线,负责构建、测试并部署到生产环境。

6.3. 潜在缺点与权衡
- 样式隔离:CSS的全局性是主要挑战。可通过BEM命名规范、CSS Modules、CSS-in-JS(如styled-components)或Shadow DOM来解决。
- 跨应用通信:应尽量减少直接通信以避免耦合。推荐方式包括:
-
- URL路由:通过地址栏传递参数(如
/restaurant/:id),这是一种声明式、低耦合的优秀方案。 - 自定义事件:用于间接通信。
- 避免共享状态:如同微服务不共享数据库一样,微前端也应避免共享数据模型。
- URL路由:通过地址栏传递参数(如
- 共享组件库:有助于保证UI一致性,但需谨慎。应让模式自然形成后再提取共享组件,并确保只包含UI逻辑,不含业务逻辑。
- 后端协作:推荐全栈团队模式,每个微前端可拥有专属的后端(BFF - Backend For Frontend),以实现完全自治。
- 打包体积膨胀:独立构建可能导致公共依赖(如React)重复打包,增加用户下载体积。可通过外部化(Externals)解决,但这又会引入版本耦合。
- 环境差异风险:微前端在"独立"模式下开发,可能与生产环境(在容器内)表现不一致,需加强集成测试。
- 运维与治理复杂度:项目数量增多,带来更多的仓库、流水线和域名管理。需要成熟的自动化工具和治理体系来应对去中心化带来的挑战

微前端并非银弹,而是一种有明确取舍的架构选择。它通过牺牲一定的简单性(增加了系统复杂度),换取了巨大的团队自治性和技术演进灵活性。
其成功的关键在于严格控制耦合、建立清晰的契约、并拥有相应的工程和组织成熟度。
7. 康威定律
任何设计系统的组织,最终都会产生一个系统设计,其结构是该组织通信结构的副本。 通俗来讲,你的软件架构,会变成你团队组织结构的样子。
- 如果你的公司有前端、后端、数据库三个独立团队,彼此沟通不畅,那么你们做出来的系统很可能就是前后端分离、数据库强耦合、接口僵硬的三层架构------哪怕技术上并不最优。
- 如果一个功能需要跨多个团队协作才能完成,那这个功能的实现通常会慢、复杂、容易出错。
- 反之,如果一个小团队能自主负责某个完整业务(比如"订单服务"),他们就更可能做出高内聚、低耦合、可独立部署的模块或微服务

7.1. 核心思想:
- 人与人的沟通方式决定了代码之间的耦合方式。
- 软件模块之间如果频繁交互,说明背后的人经常交流;如果模块隔离清晰,往往是因为团队之间很少打交道。
- 你无法设计出一个与组织沟通模式相悖的高效架构------强行这么做只会导致系统内部充满"摩擦"和"妥协"
| 策略 | 说明 |
|---|---|
| 忽视 | 不考虑组织结构,只从技术角度设计架构 → 通常失败 |
| 接受 | 让架构顺应现有团队结构(如按团队划分服务边界)→ 更现实 |
| 反向康威机动(Inverse Conway Maneuver) | 先调整团队结构,再引导出理想的架构(如组建端到端业务团队来推动微服务)→ 主动塑造架构 |
- 微服务的成功,很大程度上依赖于组织是否支持小而自治的跨职能团队。
- 领域驱动设计(DDD)中的"有界上下文"(Bounded Context)常被用来对齐业务、代码和团队边界,正是康威定律的实践体现。
- 架构师不仅要懂技术,更要理解并设计团队协作方式
8. 相关资料
- Who Needs an Architect? www.martinfowler.com/ieeeSoftwar...
- BaaS:en.wikipedia.org/wiki/Backen...
- Amazon Lambda docs.aws.amazon.com/lambda/late...
- 技术债务:www.martinfowler.com/bliki/Techn...
- 微前端:www.martinfowler.com/articles/mi...