软件架构师
软件架构师负责的是结构:一个系统如何划分为若干部分、这些部分之间如何通信、整体必须守住哪些属性,以及它如何在数年之内改变形态而不必推倒重建。这类决定数量相对少,撤销的代价相对高。本指南说明这门学科覆盖什么、它与资深工程有何不同,以及在招聘中如何判断架构层面的推理。
软件架构师做什么?
软件架构师决定一组系统如何被组织,以及这个结构如何演进。工作包括把业务领域拆分为服务或模块、定义它们之间的边界与契约、确立可用性、延迟、吞吐与恢复目标这类非功能性需求、依据这些需求选择技术、规划从现状到目标状态的迁移,以及把每个选择背后的推理记录下来,使其日后可以被理解和质疑。架构师通常跨多个团队工作,时间视野以数年计,动手程度一般低于实现这些决定的工程师。
把架构与优秀的资深工程区分开的,是判断错误的代价。多数工程决定可以在一个迭代内撤销。架构决定会把组织绑住:一条画错位置的边界要到一年半以后才被发现,那时已有三个团队围绕它构建,纠正就意味着拆开每一处跨越它的集成。正是这种不对称,使得架构师把过多的精力放在辨别哪些决定是单向的、哪些可以安全地推迟。
这门学科是被施加的约束。一个什么都允许的架构等于什么都没有决定,各团队随后会各自重新发现同样的问题,并给出不同的答案。有用的架构会收窄空间——边界在这里、服务之间这样通信、一个新组件上线前必须满足这些条件——同时在约束之内留出足够余地,让团队对自己的工作保有真正的自主。
这个角色反复出现的失效模式众所周知,值得点名。一位不再接触生产环境的架构师,其图纸描述的是设想中的系统而不是正在运行的系统,其标准以宣告而非提案的形式出现,结果就是被礼貌地忽略。真正算数的产出不是一份文档,而是一个团队确实照着构建的决定,而这通常要求架构师在问题被感受到的时候在场。
组织何时需要这项能力
架构一直在发生,问题只在于是否有人在有意识地做它。以下是隐式版本不再够用的几种情形。
多个团队在互相对着建
每个团队都在优化自己的交付,团队之间的接缝随之退化:数据重复且无人归属、同一个集成被以互不兼容的方式建了两次、一个服务的改动毫无预警地弄坏另外两个。没有哪个团队能独自修复它,因为问题存在于它们之间。
单体正在被拆分,或者拆分正在被回退
两个方向需要的是同一种稀缺能力——知道真正的接缝在哪里。按错误的线拆开,会得到一个具备单体全部耦合、却没有单体便利性的分布式系统,而这个结果远比相反的情况常见。
非功能性需求变成了合约义务
一位企业客户、一家监管机构或一项可用性承诺,把延迟、恢复时间、数据留存地或可审计性变成了义务。把这些属性事后补进一个设计时并未考虑它们的系统,往往比最初的构建还要困难。
一项重大的技术选型迫在眉睫
数据存储、消息骨干、身份提供方或云平台承诺,都会被沿用数年。这类决定往往是在时间压力下由声音最大的人做出的,而其后果在做决定的人早已离开之后才到来。
迁移必须与交付并行
在持续发布的同时替换一个核心系统,需要一套共存策略:过渡期什么走哪条路径、状态如何对账、每个阶段的回退是什么样子。迁移失败在排序上远多于在技术上。
没有人能解释系统为什么是现在这个样子
做出奠基性决定的人已经离开,推理也随之带走,于是当前的形态要么被当作神圣不可动,要么被当作随意的产物。两种读法都错,而且都会导致昂贵的失误。
核心能力
系统拆分
找到能反映业务实际如何变化的边界,使得一次典型的修改落在一个组件之内而不是横跨四个。沿技术分层而不是沿领域关注点划出的边界,通常正是「每个功能都需要多方协同发布」的系统的来源。
集成与契约
决定组件之间如何通信——同步还是异步、共享模式还是在边缘做转换——并定义稳定到可以依赖的契约。版本管理、废弃策略与向后兼容属于设计的一部分,而不是第一个消费方被弄坏之后的补救。
非功能性需求
把模糊的期待转化为关于可用性、延迟、吞吐、持久性、恢复、数据留存地与可审计性的明确目标,然后据此设计。没有被量化的需求无法被有意地满足,只能被偶然地满足。
技术选型
依据真正会咬人的需求来评估候选方案,包括运维负担、可招聘的人才范围、许可、退出成本与组织契合度。相关的问题很少是「抽象意义上哪个更好」,而是「哪个与这些约束以及将来运维它的人相匹配」。
取舍分析
明确说出每个选项付出什么、而不只是提供什么,并讲清楚正在牺牲哪些属性。一个被描述得没有缺点的架构,要么没有被分析过,要么是在被推销而不是被解释。
迁移策略
把从现状到目标状态的路径规划成一系列增量,每一步之后系统仍然可用,并把共存、对账与回退设计进去。困难的部分几乎从来不是目标设计,而是顺序。
决策记录
写下决定了什么、否决了哪些备选、假设了什么,以及什么情况足以让它被重新审视。价值在数年之后显现,那时有人必须判断某条约束是否仍然成立,还是已经悄悄失效。
失败与威胁分析
推理一个依赖只是劣化而非彻底宕掉时会发生什么、重试在哪里会放大负载、部分失败对用户呈现为什么样子,以及信任边界和数据流如何把系统暴露给攻击。
成本建模
理解一个设计在预期与非预期流量下的运行成本。技术上站得住、经济上不可持续的架构很常见,而这个发现通常伴随一张账单到来。
没有指令的影响力
让团队照着一个他们并未被强制接受的决定去构建。这项能力决定了上面这份清单是否会产生任何结果,而它恰恰是技术资历出色的候选人最常缺少的一项。
这门学科是如何实践的
架构不由一份产品清单定义,因此本节描述的是方法而不是工具。以下的实践、记法与产出物是业界普遍在用的——它描述的是这门学科的一般情况,而不是关于任何个人工作方式的说明。把它们说出名字很容易;值得寻找的证据是它们所承载的判断力是否真的存在。
建模与记法
- C4 模型
- 上下文图与容器图
- 时序图
- 领域模型与限界上下文
- 数据流图
决策实践
- 架构决策记录
- RFC 流程
- 架构评审会
- 技术雷达
- 结构化取舍分析
质量属性分析
- 延迟与错误预算
- 可用性与恢复目标
- 容量建模
- 威胁建模
- 失效模式分析
演进与迁移
- 绞杀者式迁移
- 防腐层
- 契约版本与废弃策略
- 分阶段切换与双跑
- 数据回填与对账规划
不靠守门的治理
- 适应度函数
- 自动化一致性检查
- 依赖与边界规则
- 铺好路的平台默认值
- 偏离与例外记录
证据收集
- 概念验证
- 负载与长稳测试
- 故障注入演练
- 生产遥测数据复核
- 运行成本分析
How this role works with your team
Engineers work inside your team, on your priorities, to your standards. You direct the work; Talent.ID carries the employment. The division below is the whole arrangement.
You keep
- 产品
- 业务优先级
- 路线图
- 架构
- 冲刺优先级
- 工程标准
- 日常技术协作
Talent.ID handles
- 雇佣关系
- 薪资发放
- 员工福利
- 人才管理
- 持续的员工关系
招聘时应关注什么
架构面试奖励表达的流畅,而流畅很廉价。候选人可以自信地描述各种模式,却从未与选择其中之一的后果共处过,因此有用的证据几乎总是回溯性的:他们决定了什么、代价是什么,以及当现实与图纸不一致时他们学到了什么。
后果层面的证据
问他们设计过的、数年后仍在运行的某个架构,以及其中后来被证明是错的部分。在自己的决定成熟之前就离开的架构师,永远收不到那份能让下一个决定更好的反馈。
- 在一个系统里待得足够久,见过一个设计变老
- 能说出一条自己画错位置的边界,并描述它产生的症状
- 能区分「失败的设计」和「成功但被规模甩开的设计」
双向陈述的取舍
给出一个设计决定,问它的代价是什么。谁都会主张;问题在于他们是否愿意说出正在放弃哪些属性,以及在什么条件下他们偏好的选项会变成错的那一个。
- 主动讲出自己所推荐方案的弱点
- 能指出哪些条件会改变这个答案
- 把运维负担当作一等成本,而不是实现细节
与运行中系统的距离
象牙塔式的失败是真实存在的,而且大体上可以在面试阶段避免。问他们所负责领域里最近一次生产故障带来了什么认识,以及他们设计的架构与他们去查看时看到的是否一致。
- 最近读过生产遥测数据,并说得出什么让他意外
- 既知道自己的设计构建成本,也知道运行成本
- 因为团队实际上难以遵守而修订过某条标准
对迁移的现实感
目标架构是简单的那一半。问他们会如何在组织继续交付的同时把它迁过去,并听每一个中间步骤之后是否都留下一个可用的系统。
- 规划的是共存,而不是一次切换事件
- 为每个阶段设计回退,而不只是设计终点
- 把两套模型必须同时维护的那段时期计算在内
决定如何变得具有约束力
只活在文档里的架构改变不了任何事。问他们的某个决定实际上是怎么进入代码的——通过评审、工具、默认值、一致性检查还是说服——以及他们如何察觉偏离。
- 相比成文规则,更偏好自动化检查与合理默认值
- 能描述自己发现团队已经偏离之后做了什么
- 写决策时会包含被否决的备选与失效条件
把非功能性需求量化
问他们如何在一个真实系统上确立可用性或延迟目标。有区分度的回答会把它追溯到某个业务后果,而不是一个听上去足够严肃的惯例数字。
- 目标来自后果推导,而不是来自惯例
- 知道可用性再提升一档的成本是多少
- 既往上争取过目标,也往下争取过
克制
过度架构的破坏力至少不亚于架构不足,而且解开要难得多。问他们何时选择了更朴素的方案,以及他们刻意没有为之做设计的某项能力。
- 能描述自己拒绝引入一项自己喜欢的技术
- 能区分不需要仪式的可撤销决定与需要仪式的决定
- 为一个可信的下一阶段而设计,而不是为一个想象中的终局
值得一问的面试问题
供您自己的评估流程使用。每一题针对的都是难以背诵的推理,说明部分描述的是答案往往揭示了什么,而不是正确答案。
讲一个你设计的、至今仍在生产运行的架构。它让哪些事情变难了,而这是你当初没有预料到的?
What a strong answer shows
他们是否收到过来自自己决定的反馈。遗憾的具体程度就是信号——一段关于复杂度的泛泛感慨,通常意味着他们在账单到来之前就离开了。
你如何判断一个决定必须现在做,还是可以安全地推迟?
What a strong answer shows
对可撤销性的把握,这是架构层面的核心直觉。要看推迟是被当作换取信息的有意手段,还是仅仅意味着没有看法。
拿一个你熟悉的系统。你会把边界画在哪里不同的位置,依据是什么?
What a strong answer shows
拆分是从领域如何变化推理出来的,还是从一张见过的图里搬来的。较强的回答会引用变化模式、实际观察到的耦合,以及团队结构的形态。
你接手了一个自己并不认同、且已经部分建成的目标架构。你会怎么做?
What a strong answer shows
对沉没成本与组织现实的判断。两个极端都令人担心——接受一个确实不安全的方向,或者仅仅因为不是自己会选的就推倒重来。
你参与过的某个系统的可用性目标是怎么定下来的,最后那一档提升的成本是多少?
What a strong answer shows
非功能性需求是被推导出来的还是被背出来的。成本这个问题能把「为一个目标做过设计的人」和「引用过一个目标的人」分开。
讲一条你定下、但团队没有遵守的标准。你从中得出了什么结论?
What a strong answer shows
被忽略时的反应,而每个架构师都会经历这件事。要听的是对「为什么遵守很难」的好奇,而不是一段关于别处纪律不足的叙述。
要让你建议我们放弃当前依赖的某项技术,你需要先看到什么?
What a strong answer shows
变更是基于证据提出的还是基于偏好提出的。较强的回答会事先设定一个阈值,并把转换本身的成本计算在内。
你写的架构文档里,哪些是你认为真的有人在读的?你怎么知道?
What a strong answer shows
对「产出」与「被消费」之间落差的诚实。正视过这件事的架构师,往往已经把精力从文档数量转向了决定、默认值与对话。
What this looks like in practice
A hypothetical scenario, written to show how the working model applies. It does not describe a Talent.ID client or a completed project.
- Challenge
- 某组织运行着一个由多个团队并行扩展的核心系统。各处集成是各自独立建起来的,共享数据的归属并不清晰,而一项客户承诺又带来了当前设计从未打算满足的恢复与数据留存地义务。需要一个结构性方向,同时交付不能停。
- Approach
- 追加的资深能力在客户自己的架构实践之内工作——客户的评审会、客户的标准、客户的决策记录、客户的技术方向。结构性权限仍留在原处;追加的能力为客户所做、并由客户拥有的决定提供分析、书面备选方案与实现投入。
- What this adds to the team
- 该组织获得了投入结构性工作的经验能力,同时保留架构权限、产品所有权,以及对每一个约束其系统的决定的最终决定权。
Related disciplines
Frequently asked questions
- 软件架构师与技术负责人有什么区别?
- 影响半径与时间视野。技术负责人对一个团队数周到数月的技术工作负责,贴近代码,通常可以在一个迭代内纠正一个不好的判断。架构师跨系统、跨团队,以数年为视角工作,一个不好的判断会在无人察觉之前渗透进所有基于它构建的东西。两个角色是互补的:架构设定团队之间的约束,技术领导在约束之内做出好的决定。
- 软件架构师还应该写代码吗?
- 不一定要有产量,但需要与运行中的系统保持足够接触,好让自己对现实的模型保持准确。这种接触可以来自原型、评审、参与故障处理或阅读遥测数据,而不必是常规的功能开发。完全没有这种接触的架构师,会开始为一个「别人向他描述的系统」做设计,而这几乎就是所有象牙塔抱怨背后的机制。
- 规模较小的组织需要专职架构师吗?
- 通常不需要设为独立岗位。在只有一个产品和两三个团队时,架构决定的数量少到可以由资深工程师和一位技术领导者承担。需求出现在决定开始跨越团队边界时、在多个系统必须互操作时,或者在某项承诺让非功能性属性变得不可谈判时。在还没有需要归属的跨领域结构之前就设立架构师,往往会得到一套在寻找问题的治理。
- 架构决策记录到底带来什么?
- 它保存推理,而推理比代码衰减得更快。一份记录写明决定了什么、否决了哪些备选、假设了什么,以及什么会足以让方向改变。它的价值在日后显现,那时有人必须判断某条约束是否仍然成立。只记录结果、不记录被否决的选项与假设的记录,提供的价值非常有限,这也是许多团队认为这项实践是形式主义的原因。
- 如何分辨好的架构与昂贵的架构?
- 看复杂度是否在回应一个确实存在的需求。好的架构让预期中的变化变便宜,并说明它没有为哪些变化做优化。昂贵的架构为没有人提出过的变化预先构建灵活性,并在之后交付的每一个功能上收费。实用的检验方式是:架构师能否说出每一块结构分别是为吸收哪一种具体压力而存在的。
- 架构可以由一个群体而不是一个人来负责吗?
- 可以,而且在许多组织里效果更好。一群资深工程师共同做结构性决定,配合明确的收敛方式和一份决定记录,得到的决定比某个人下达方向更有认同度。群体不容易做到的,是在数年之间保持一致性而没有人为连贯性负责,因此常见的形态是共同决策加上一位有名有姓的记录守护者。
- 软件架构师如何与现有的工程团队协作?
- 作为您架构实践的参与者,而不是它的替代。在技术团队扩展的安排下,贵组织保留架构权限、技术方向、工程标准、路线图与产品所有权;结构性决定由您的人做出并批准,工作也由您的团队指挥。在 Talent.ID 一侧,这项安排只涉及雇佣:雇佣关系本身、薪资发放、员工福利与人才管理。架构决策权不会随之转移。
Tell us what your team needs
Describe the gap — the work, the stack, the way your team runs — and we will tell you what we can support. If it is not something we can help with, we will say so.