ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

软件系统架构图参考案例:读图顺序、C4模型与避坑指南

软件系统架构图参考案例:读图顺序、C4模型与避坑指南

简介:这份PDF是一份软件系统架构设计的典型参考案例,以共享平台为例,完整展示了逻辑架构、技术架构与系统总体架构三大板块的设计思路。内容涵盖应用系统建设、资源采集、数据分析与展现等逻辑模块划分,以及基础层、应用数据层、应用支撑层、应用管理层、展现层的分层设计,并补充了标准规范体系、应用接口管理和用户角色分类说明。适合软件架构师、系统设计师、项目经理以及需要在方案汇报或课程作业中绘制架构图的开发者参考。资源包大小为2.75MB,仅含1个PDF文件,便于直接阅读和打印。目前已有1243人浏览学习,页面中针对每张架构图配有详细文字解析,可帮助读者理解各层级的绘制重点与关联关系,从而迁移到自己的项目设计中。

1. 软件系统架构图不是画框连线:参考案例解决的是读图和画图的顺序问题

一份《软件系统架构图_参考案例.pdf》表面上是几十张示例图,真正的价值却是给了你一套读图的顺序。新手拿到架构图最容易犯的错,是从中间某个核心服务开始看,结果系统边界没圈出来,依赖关系也理不清。我习惯把这套参考案例当作坐标系:先定位系统边界,再沿数据流走一遍,最后才关心每个框内部的技术选型。这个顺序反过来,正好就是画图的顺序。这套方法主要面向需要画图、评审图、维护架构文档的开发者,无论你是准备架构评审、写技术方案,还是给新团队讲系统全貌,都能直接照着用。

2. 架构图的常见形态与选型:分清楚你手上这张图属于哪一层

"参考案例"这四个字容易让人产生一个误解:照着画一张就完事。实际上,一份正经的架构图参考案例,通常不是一个系统的单张图,而是一组图。同一个系统可以有逻辑视图、开发视图、进程视图、物理视图,再穿插几个核心场景串起来,这就是经典的 4+1 视图模型。拿到参考案例先别急着抄,先判断每张图在回答什么问题。用错图是后面所有翻车的起点,比画得丑严重得多。

2.1 逻辑视图与物理视图:先分清图里画的是职责还是机器

逻辑视图描述的是系统在概念上分成哪些模块,每个模块承担什么职责,模块之间如何依赖。它不关心这些模块跑在哪台机器上,也不关心用什么协议,是一种偏"理想化"的系统结构。物理视图则反过来,画的是服务器节点、进程、端口、网络分区、存储设备这些真实存在的部署资源。判断方法很简单:图里出现 IP、端口、主机名、容器节点,基本是物理视图;出现业务模块、服务名、调用方向,大概率是逻辑视图。

这两类图不能互相替代,更不能混着画。逻辑视图用来讨论职责划分和依赖边界,适合方案设计阶段;物理视图用来讨论容量、隔离和故障域,适合上线评审与运维阶段。常见问题是很多团队只画一张"混合图",把业务服务和物理机器放在同一张图里,结果评审时一半时间在争论"这个框到底代表服务还是进程"。我的做法是从参考案例里找到同一套系统的两张图对照着看:先读逻辑视图理解职责边界,再读物理视图理解部署约束,最后用场景视图验证端到端路径。

相比这两类,开发视图和进程视图出现的频率低一些,但参考案例里往往也有。开发视图回答"代码怎么组织",对应模块、包、目录结构,适合给新加入团队的开发者看;进程视图回答"运行时进程怎么协作",涉及进程间通信机制、线程模型和生命周期。如果你拿到一张图,里面的框既不是业务模块也不是服务器,那多半就是这两类之一。先归好类,读图才不会跑偏。这个归类动作每天可能只需要花十秒钟,但它决定了你后续所有判断的坐标系,坐标系错了,后面读得越仔细错得越远。

2.2 分层架构、微服务架构与部署架构图的读图差异

分层架构图是参考案例里出现频率最高的。读法是"从上往下看调用链":接入层、应用层、领域层、数据层逐层调用。这里要重点检查有没有跨层调用,比如页面模块直接访问数据库,或者业务服务绕过网关直连外部系统。跨层调用是评审时最容易被点名的设计坏味道,在分层图上非常显眼——一条线从最上层直接插到最下层,视觉和逻辑上都很突兀。

微服务架构图的读法完全不同,关注服务边界、数据归属和协作方式。拿到图先找三点:一是网关和服务之间的连线,那是入口流量;二是服务之间的连线,要区分同步调用与异步消息;三是每个服务下方的存储框,代表数据是否独占。一个常见误区是认为微服务图里的服务越多越好,实际上好的参考案例反而会刻意控制显式连线数量,把公共服务、消息总线这类基础设施单独画一层,避免线条交叉成蜘蛛网。

部署架构图又是另一套读法,回答"系统跑在哪里、怎么容灾、网络怎么分区"。看部署图有个技巧:先数副本数,再看负载均衡放在哪个位置,最后确认状态存储是不是单点。单点状态存储是部署图里最大的隐患,一眼就能看出来,容灾方案的所有讨论基本都围绕它展开。

下面这张表是我评审时常用的对照方式,也可以作为参考案例归类的依据:

图类型核心回答的问题第一眼看哪里最大的坑
分层架构图模块职责与层间依赖最上面的接入层和最下面的数据层跨层调用不标注出来
微服务架构图服务边界与协作方式网关与服务之间的连线同步异步混用线型或颜色
部署架构图节点拓扑与容灾副本数和网络分区把逻辑组件叠画进物理节点
数据流图请求路径与数据存储数据从哪来、最后落在哪缺存储位置和一致性说明

选型建议一句话收住:技术方案文档用逻辑分层图加数据流图;系统上线前评审用部署架构图;涉及服务拆分或改组的讨论,用微服务架构图。参考案例里如果某张图让你看得累,通常不是图本身丑,而是信息层次太多被压在一张图里。先用前面的归类方法把图拆开看,比硬记任何画法都有用。

注意:先归好类再读图,这是读参考案例的第一步,也是最容易被跳过的一步。

3. 从参考案例反向拆解:读一张架构图的 4 个信息层

架构图的信息量很大,直接读很容易淹没在细节里。我一般把读图拆成四步:圈边界、走数据流、标依赖、验证闭环。这套顺序在画图时反过来用,就是一张图的骨架。参考案例的价值就是让你反复练这个顺序,练到形成条件反射。

3.1 第一眼先圈系统边界,再列外部依赖清单

拿到一张架构图,第一件事不是找核心服务,而是先找图的边界。系统的入口在哪里:用户端、外部系统、消息源;系统的出口在哪里:数据库、第三方服务、消息队列。边界圈出来了,"系统从哪来到哪去"就有了答案。

具体做法是暂时不看图中部的任何框,只看外圈。凡是线条穿出图边界、或者引向图例里标记为"外部"的实体,都标出来。比如我拿到一张订单系统的参考案例图,不会先看中间那些服务,而是先绕图一周:图最上边是"消费者App"和"运营后台",最下边是"订单库"和"消息队列",右边界还有一个"外部短信网关"。这就是边界。之后列一张外部依赖清单,包含三列:依赖对象、方向、协议。这张图的外部契约立刻清楚了:App 走 HTTPS 进来,短信网关是系统调出去,消息队列是异步出口。

外部依赖的连线往往决定部署和容灾方案,所以这一步不能省。内部模块可以在意,但外部依赖通常查不到文档,只能靠架构图建立认知。如果参考案例图里外部实体画得含糊,比如只有一个"第三方"没写具体系统,这张图的信息就是不完整的,拿到评审现场一定会被追问。

3.2 沿数据流走一遍:同步调用与异步消息怎么区分

边界圈定后,选一个端到端请求,沿图的连线完整走一遍。走的过程中回答三个问题:请求经过哪些模块、在每个模块是同步等待还是异步触发、数据最终落进哪些存储。

举个例子,从"用户下单"这条路径走:消费者App 到 API 网关,网关到订单服务,订单服务调库存服务,最后订单落库。走到支付回调这条线时,我会停下来问自己:订单服务等支付结果,是同步还是异步?答案显然是异步,因为支付结果要等用户操作,不能占着一个同步连接干等。而扣减库存必须是同步 RPC,因为用户需要立刻知道是否成功。这样一条路径走完,图里的静态方块就变成了动态过程,系统的行为才算真正理解。

图里区分同步异步的方式一般是实线表示同步调用、虚线表示异步消息。如果参考案例图没有区分,属于信息缺失,需要在评审时明确追问。异步消息还要看消息中间件的角色:点对点队列还是发布订阅主题,两者的业务解耦程度完全不同,图面上必须能读出来。走数据流时还要有意识地数跳数:从入口到落库之间经过几次调用,超过四次通常意味着中间层有冗余,可以思考是否合并。这个"数跳数"的习惯帮我发现过好几处无意义转发。

存储位置的读法也有讲究。每个数据落点都要回答三个子问题:主副本在哪、读路径走哪个节点、多副本之间是同步复制还是异步复制。这三个问题决定数据一致性的边界,图里如果不标注,等系统上线运维期一定会出问题。读参考案例时遇到没标注的,直接在旁边写"待确认",比假装看懂有用。

3.3 信息提取清单:一张图该挖出来的四类资产

为了不漏信息,我用固定的提取清单读完每一张参考案例图。这个清单也可以反向用于自查自己画的图:

信息类别要提取的内容图上对应位置
边界系统入口、出口、外部依赖清单图的外圈和穿出线条
数据流端到端路径、同步异步标记连线类型与方向
依赖模块间调用方向、协议标注框之间的箭头
存储持久化位置、主从关系数据库框及其连线

读图时顺手在空白处或笔记里补缺失信息,比如某条线没有标协议,就记一条"待确认"。这样一张图读下来不是走马观花,而是一份能直接用于评审的输入物。参考案例的价值就在这个环节:你反复用同一套清单读不同系统的图,慢慢形成肌肉记忆,之后看到任何架构图,第一反应都是这套四步走。直接读图的人记住的是"这张图长什么样",用清单读图的人记住的是"这个系统怎么运转"——前者是感性印象,后者是可复述的结构认知,评审或答辩时能复述结构的人明显更占优势。

4. 照着参考案例的画法落地:从空白画布到一张能过评审的架构图

读图顺序理清之后,画图就变得简单了,因为画图就是读图的逆过程:先圈边界,再画模块,再连数据流,最后标协议和存储。这一章讲的是如何按这个顺序从空白画布落成一张经得起评审的图。

4.1 用 C4 模型固定层级,从源头避免粒度混乱

画图时最常见的翻车是粒度不一致:同一张图里,一个框代表整个子系统,另一个框却代表一个功能模块,信息层级混乱。解决办法是先定分层模型,我用的是 C4。C4 分四层:Context 系统上下文、Container 容器、Component 组件、Code 代码。画架构图最常用的是前两层:系统上下文图回答"这个系统跟谁交互",容器图回答"这个系统内部由哪些可独立部署的单元组成"。

我的习惯是两层分开画,各画一张。系统上下文图画外部边界和依赖,容器图画内部结构和协作。两层分开之后,粒度自然统一,不会出现"子系统跟功能模块平级连线"的混乱。很多人想一上来就画一张"包含一切"的大图,结果每个框都含糊不清。参考案例里让你觉得"信息量刚好"的图,基本都是层级分开的。

C4 的另一个价值是命名规范。每个框的名字必须能说清职责,比如"订单服务:负责订单生命周期管理"。如果框的名字写成"订单模块"或者只有一个"订单",说明职责没想清楚。这个标准反过来可以用在评审上:看到名字含糊的框,直接问职责边界,答不上来的地方就是设计没想透的地方。

4.2 先出文本版再精修排版:PlantUML 快速出图示例

动手画图时,我一般先用文本形式把结构定下来,再拿到可视化工具里精修排版。文本形式的好处是 diff 友好、方便评审、不会把时间耗在拖动框位上。常见做法是用 PlantUML 写一版结构稿。下面是一个分层架构参考案例的简化示例:

@startuml title 订单系统分层架构(参考案例简化版) skinparam componentStyle rectangle package "接入层" { [Web 管理后台] as web [开放 API 网关] as api } package "应用层" { [订单服务] as order [支付服务] as pay [库存服务] as stock } package "数据层" { database "订单库" as db_order database "库存库" as db_stock } web --> order : HTTPS 创建订单 api --> order : HTTPS 查询订单 api --> pay : HTTPS 发起支付 order --> stock : RPC 扣减库存 pay --> order : 异步回调通知 order --> db_order : SQL 读写 stock --> db_stock : SQL 读写 @enduml

这段代码画了三层结构:接入层放 Web 管理后台和 API 网关,应用层放订单、支付、库存三个服务,数据层放两个数据库。箭头的方向统一为"调用方指向被调用方",冒号后面写协议和动作。这里特意把支付回调标成异步,因为如果同步异步都用实线,评审现场就会有人问"这条到底等不等结果"。

参数说明:skinparam componentStyle rectangle 让所有组件以矩形显示,视觉统一;package 对应架构图里的分层;database 类型会把存储节点画成圆柱体,一眼区分数据层。想调整线型时,--> 表示同步调用,-->> 表示异步消息,->> 表示带返回值的同步调用。我一般只用这三种,线型太多会显著增加读图负担,参考案例里的成图也普遍遵循这个原则。

4.3 draw.io 导出与三条成图规范

文本版确定结构后,下一步是导到 draw.io 里精修排版。选它主要因为三件事:网格对齐可靠、图层管理顺手、团队协作不用引入额外账号体系。成稿导出统一用 SVG,配合 8 像素网格对齐,字体嵌入文件,避免换一台机器打开就乱版。批量导出可以写进命令:

drawio -x -f svg -o architecture.svg order.drawio

-x 表示导出,-f 指定格式,-o 指定输出文件名。如果团队有持续集成环境,建议把这条命令挂进流水线:每次架构图变更后自动导出 SVG 并发布到文档站点,从机制上消灭"图改完了但文档里还是旧图"的问题。

成图规范上有三条约定,参考案例里的合格成图也基本如此。第一,颜色只表达语义类别,基础设施一种颜色、业务服务一种颜色、外部系统一种颜色,禁止彩虹配色;第二,每个框必须有名字加一句职责说明,只写名字的框在评审时必然被问"这个框是干嘛的";第三,图里必须有图例,说明箭头方向、虚实线含义、颜色分类。页面尺寸和缩放也要提前定:架构图经常被投影到会议室大屏,或者被塞进 Word 文档,我一般把画布设成宽屏比例,图上字号不小于 10 号,导出字号不低于 12 号,保证投屏时最后一排也能看清。

提示:图例不是可选项,是刚需。颜色超过三种但图例没写的图,评审现场一定有人问"这个颜色代表什么"。

5. 架构图避坑指南:参考案例里看不到的 5 个血泪踩坑记录

画得多了,坑自然就见过。以下五条来自实际评审和交付现场的血泪记录,每条按"现象 → 原因 → 解决"写,可以对照检查自己的图。一条一条过,比反复改版重画效率高。

5.1 把部署架构图当成系统架构图交差

现象:交付物里只有一张物理部署图,画了服务器、容器节点、负载均衡,看起来非常专业,但没有任何一张图说清楚系统分成哪些业务模块、模块之间什么依赖关系。评审会上大家讨论半天,发现无法评价模块划分是否合理。

原因:部署图最好画,框多、连线多、一眼望去信息量很大,但实际上它只回答了"跑在哪、有几份",没有回答"职责边界在哪"。画图的人用视觉密度替代了设计思考。

解决:架构文档分两层,逻辑层画模块与依赖,物理层画部署与容灾。顺序上先画逻辑层,再叠加物理层,两层缺一不可。落地建议:交付评审材料时,逻辑图放第一页,部署图放附录,评审人第一眼看到的一定是逻辑结构。

5.2 箭头方向不统一,评审时各说各话

现象:同一张图里,一些箭头指向被调用方,另一些指向调用方,还有个别双向箭头。评审时两个人对同一根箭头的理解完全相反,为"到底谁调谁"争论一小时。

原因:画图时没有约定箭头语义,看到两个框有关联就随手画线,自己心里清楚,别人完全不知道约定是什么。

解决:团队内固定一条约定:"箭头永远指向被调用方",或者在图中注明"箭头指向数据流向"。我用的是前者,它更贴近代码里的调用方向。落地建议:这条约定可以从下一个项目开始执行,再把旧图统一回改一遍,成本比想象中低。

5.3 组件粒度忽粗忽细,一张图混三层抽象

现象:一张图里,"订单系统"是一个大框,"用户注册"是一个小框,两者直接连线。读者完全分不清哪些框代表系统、哪些代表模块、哪些代表服务,层级混乱。

原因:没有固定分层模型,想到哪画到哪,把系统级、模块级、类级别抽象混在一张图里。这是架构图重灾区,几乎所有新手图都有这个问题。

解决:按 C4 分层,系统上下文图和容器图分开画。如果必须合成一张,用大框套小框表达层级,小框必须从属于某个大框,不允许跨层级直连。落地建议:给每个框加一个类型前缀,比如 [S] 代表系统、[M] 代表模块、[C] 代表服务,图例里写清楚,扫一眼就能检查粒度是否统一。

5.4 图例缺失,颜色和线型全靠脑补

现象:图上用了红黄蓝三种颜色,实线虚线点线都有,但图角落没有任何图例。评审时每个人对红线的理解都不一样:有人说代表故障链路,有人说代表告警路径,有人说代表异步调用。

原因:画图的人知道颜色含义,默认看图的人也懂。这个默认通常不成立,尤其是跨团队评审时。

解决:图例画在架构图右下角,四行以内写清楚:颜色对应哪类组件、实线虚线分别代表什么、箭头方向约定。图例紧跟版本号和最后更新日期,方便追溯改图历史。落地建议:画完图之后自己先做一次"盲读测试"——遮住图例以外的所有提示文字,看能不能凭图例读懂全图。

5.5 图归档三个月后和代码彻底对不上

现象:三个月后按架构图排查线上问题,发现图里标注的"订单服务直连数据库",实际代码早改成通过统一数据服务访问,图里还有已经下线半年的旧模块。按图索骥的结果是白忙一场。

原因:图是一次性产物,画完就归档,之后没人维护。代码一直在演进,图停在画完那天,自然越来越失真。

解决:把图纳入文档同步流程。凡是涉及模块增删、依赖变更的代码评审,同步更新对应架构图;图内放"最后更新日期"字段,超过一个月没更新的图在文档站点上标记提醒。落地建议:把"更新架构图"写进代码评审的完成定义里,没有更新图的分支不允许合入。维护架构图本质上是维护团队对系统的共识,不维护的图比没有图更危险。

6. 用架构图反向审查系统设计,让参考案例变成团队的活资产

图画完不是终点,而是评审的起点。我常用的做法是"反向走图":拿着画好的图,挑三根关键箭头,逐个问三个问题——谁发起的、什么协议、失败怎么办。比如订单服务调用库存服务这根箭头,发起方是订单服务,协议是同步 RPC,失败怎么办?图旁边如果不写"重试三次、失败走补偿事务",这根箭头就是不完整的。这个习惯帮我提前拦住过好几次设计漏洞,比读十遍代码效率高得多。

验证工作流上,我习惯每两周做一次"图与代码对账":随机挑一个模块,核对图上标的依赖、协议、存储,跟配置中心、接口定义、数据库连接串逐一对比。对不上的地方标记 TODO,在下一个迭代修正。对账不需要自动化工具,胜在勤快。某团队把这个习惯坚持了两个迭代周期,架构图准确性明显提升,评审会议从各说各话变成对着同一张图讨论问题。

把参考案例变成团队资产,做法很朴素:在文档站点建一个架构图目录,按系统分别存放,每张图内嵌版本号和更新日期;新画图的人先从目录里找相似案例改,而不是从空白画布开始。我自己吃过最大的亏,就是花两小时画了一张同事已经画过 80% 的图。现在我的习惯是动手前先翻目录,翻不到才从零画。

最后提醒一句:架构图是设计沟通的载体,不是应付评审的作业。能让你在十分钟内讲清楚"系统从哪来、经过谁、落在哪、挂了怎么办"的图,就是合格的图。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进