尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

一张图讲清系统架构:diagram-design方法论与工程实践

一张图讲清系统架构:diagram-design方法论与工程实践 去年做技术评审我花了三个小时画了一张系统架构图投影出来之后前端组长盯着看了十秒钟问了一句“所以你画的这条虚线箭头到底是调用还是消息推送”那一瞬间我意识到一个问题——很多人画 diagram 只是把脑子里的信息“倒”到画布上就完事压根没想过“设计”。但 diagram-design 这件事本质上是把抽象关系翻译成视觉关系让看图的人在最短时间内建立起和画图人一致的心理模型。翻译得差图就是噪音翻译得好图就是文档里最值钱的部分。这篇文章不打算罗列某个工具的上百个快捷键而是想从 diagram-design 的完整链路出发讲清楚我在一次次评审、文档编写、团队协作中沉淀下来的方法论动手之前想什么、工具怎么选、视觉规范怎么定、落地实战有哪些坑。适合正在写技术文档的工程师、要做方案汇报的架构师、以及所有需要“画一张讲得清楚的图”的人。1. 先搞明白一张好图不是信息堆砌而是视觉翻译1.1 信息层级一张图只能有一个主角很多图乱第一个原因就是想表达的东西太多。系统里有十来个服务、七八条链路、五六个存储恨不得一个不落全画上去。结果就是满画布都是方框谁都不突出谁都可以被忽略。我自己的经验是动笔之前先问一句这张图的主角是谁如果是核心调用链那存储和配置中心就该弱化如果是部署拓扑那业务链路就该简化成一条粗箭头。主角只能有一个其他全是背景。具体操作上可以给图里的元素分三个层级核心链路用深色、粗线条、大尺寸支撑模块用中性色、正常尺寸外围依赖用浅色、小尺寸、甚至淡化成背景。看的人第一眼落在核心链路上第二眼扫到支撑模块第三眼才去读外围依赖。这个视觉顺序一旦建立图的表达能力立刻上一个台阶。1.2 读者决定细节密度同样一张订单系统架构图给CTO看和给刚入职的应届生看画法完全不一样。给决策者看要突出的是“这个方案分几块、数据怎么流动、瓶颈在哪”细节越少越好最好能压缩成一页。给新同学看要画清楚每个模块的职责、每个接口的出入参、异常处理往哪走这时候图可以拆成多张甚至一张图画不下就按子系统拆分。我踩过的坑是一张图想同时满足所有人于是加了大量注释和分支结果汇报时被说“太啰嗦”给新人培训时又被说“看不懂”。后来我养成了一个习惯画图前先写一句话——这张图是给谁看的他要从中获得什么信息如果答不上来就先别打开画图工具。1.3 载体决定画法PPT、文档、白板、大屏不是一回事同样一张图放在PPT里和在文档里、在白板上现场画、投到大屏上设计逻辑完全不同。PPT里的图是“讲”出来的元素要少字号要大最好能一个动画一个动画地出现跟着讲解节奏走。文档里的图是“读”的可以承载更多细节但要有清晰的分区和编号方便读者跳着看。白板上的图是“长”出来的得从左上角开始画边画边讲所以结构要线性不能一开始就铺满整个板面。大屏上的图则是“播”的要考虑远距离观看线条要粗对比要强细枝末节一概不要。2. 动手之前先回答四个问题2.1 这张图的目的是解释、说服还是记录这个分类比想象中重要。解释型图的目标是让读者理解一个概念或流程比如“消息队列是怎么工作的”重点在因果和顺序。说服型图的目标是推动决策比如“为什么要引入新的缓存方案”重点在对比和收益。记录型图的目标是沉淀事实比如生产环境的部署架构重点是准确和完整哪怕牺牲一点美观。不同目的决定了图的取舍方向。解释型图可以适当牺牲精确性换取直观比如把复杂的重试机制简化成一个循环箭头。说服型图要突出“前后对比”和“关键指标”可以用不同颜色把优化前后的路径标出来。记录型图则要把每个组件的版本、数量、连接方式都写清楚这种图往往追求完整但读起来会比较累。我见过很多团队把记录型图画得像解释型一堆箭头、一堆颜色结果运维照着部署时发现少画了一个端口映射。这类事故的根源就是画图的人没有搞清楚这张图到底是干嘛用的。2.2 核心链路是什么任何系统都能拆出一条主链路比如“用户请求→网关→服务A→数据库→返回”。这条链路是整张图的骨架其他一切都是围绕它展开的。确定核心链路之后先把它画出来再逐步往外扩展。这个过程有点像写文章先列大纲——大纲立住了细节往里面填才不会乱。如果发现核心链路本身有两条甚至三条那说明这张图该拆了要么拆成多张要么把非核心的那条降级成虚线标注。从实操来看90%的混乱图都是因为核心链路不清晰。读者盯着密密麻麻的箭头无法判断哪条是主路、哪条是旁路自然就“看不懂”。2.3 边界画到哪里很多图之所以画不完问题出在边界上。画一个订单系统要不要把上游的支付网关画进来要不要把下游的物流系统画进去把相关方全画进来图就失控了。我的建议是只画“本图要讨论的范围”范围之外的东西用一个“外部系统”灰色框打包处理。打个比方画房间的平面图只需要把墙画清楚不需要把隔壁邻居家的家具也画进来。边界明确之后图就能收敛读者也能清楚地知道“这张图只管这一段”。2.4 异常路径怎么处理正常流程画完之后异常路径是很多人的噩梦。超时、重试、降级、熔断全画上去图就花了不画又显得不严谨。我的做法是主流程画全异常路径用统一的虚线小红点标注在图的角落配上编号注释。比如在主链路的某个调用旁标一个“①”图底部写“①超时重试3次仍失败则降级返回缓存”。这样既保留了异常信息又不破坏主流程的视觉连续性。3. 工具选型没有最好的画图工具只有最匹配的场景3.1 代码生成型工具Mermaid、PlantUML、D2代码生成型工具的特点是“用文本描述图结构”改起来快天然支持版本管理适合放在仓库里和代码一起维护。Mermaid 语法简单渲染出来的图风格清新是目前技术文档里最常见的选择。PlantUML 更老牌UML 支持最全时序图和用例图表现力强但默认样式比较陈旧。D2 是后起之秀语法更现代布局引擎也更聪明连线交叉问题比前两者少。这类工具的共同弱点是布局可控性差。你想把一个节点放在画布正中间、把另一个节点放在它右下方代码生成工具不一定听你的因为布局由算法决定。所以代码生成型工具适合“结构清晰、层级明确”的图比如模块划分、时序交互、ER关系不适合“强排版要求”的视觉型图。我用文本的方式演示一个简单的结构描述方便你理解这类工具的输入长什么样核心服务用户服务── 存储层MySQL 核心服务用户服务── 缓存层Redis 核心服务用户服务── 消息队列Kafka └─ 外部依赖风控服务虚线箭头标注这段文本渲染出来就是一张带箭头的简单模块图。改起来很快想加一个节点就多写一行想改连线就改箭头方向。这类工具的核心理念是“图即代码”图跟着代码评审走跟着提交记录走。3.2 手动拖拽型工具Draw.io、Excalidraw、FigJam、OmniGraffle手动拖拽型工具把布局控制权完全交给你想放哪就放哪所见即所得。Draw.io 免费、功能全、支持本地文件适合画严肃的架构图和网络拓扑图。Excalidraw 走手绘风格画出来的图有一种天然的“草稿感”反而降低了读者的心理压力适合方案讨论和快速原型。FigJam 是 Figma 家的白板工具多人协作体验很好适合线上工作坊。OmniGraffle 是 macOS 上的老牌工具模板丰富风格偏设计向但价格不便宜。手动拖拽工具的劣势也明显排版全靠手调一旦图的规模变大对齐和维护会花掉大量时间。而且文件格式通常是私有的不方便直接做文本 diff。3.3 我的选型建议场景推荐工具理由技术文档、README、WikiMermaid文本即图版本管理友好渲染快UML、时序图、用例图PlantUMLUML 支持完整语法成熟复杂架构图、网络拓扑Draw.io免费、离线、功能全面方案讨论、快速原型Excalidraw手绘风降低正式感脑暴友好团队在线协作白板FigJam多人实时编辑音频/便签一体设计稿级别的架构图OmniGraffle / Figma排版自由度最高适合对外汇报工具只是手段不是目的。我见过用 Excalidraw 画生产环境架构图的团队也见过用 Mermaid 画得很精致的团队。关键是选一个你愿意长期用、团队里其他人也能上手的别把时间耗在工具切换上。4. 一套能直接抄走的 diagram 视觉规范4.1 对齐与间距干净感的来源很多人觉得“高手画的图干净”其实就是对齐和间距做得好。元素之间对齐、间距统一哪怕配色一般看起来也会舒服。实际操作中我习惯把画布设置为网格对齐所有方框的尺寸取偶数间距保持 8 的倍数。比如两个模块之间留 8px、16px、24px不要出现 13px、17px 这种随意间距。模块内部文字与边框之间至少留 8px 的 padding避免文字贴边。还有一个很容易被忽略的细节同一层级的方框宽度尽量保持一致。一行排四个服务如果每个宽度都不一样视觉上会特别碎。先拖一个基准框复制四个再改文字这比一个个去画要快得多。4.2 配色别超过三个主色语义必须一致配色是图中最容易翻车的地方。红、黄、蓝、绿、紫全上图立刻像游乐场。我推荐的配色方案是一个主色用来标记核心链路或重点模块一个中性色灰色系用来画支撑模块一个强调色用来标记异常、告警或需要注意的点。如果需要表示“已上线/规划中/已废弃”之类的状态可以在这个基础上增加对应的状态色但每种状态色只允许出现在状态标签上不参与模块染色。另外同一张图里同一个颜色只能表示同一个含义。如果橙色代表“用户端”那所有用户端相关的模块都必须用橙色不能这个用橙色、那个用紫色。颜色语义一旦混乱读者就会反复确认图的效率就大打折扣。4.3 形状与线条别自创语法画 diagram 时形状是有默认语义的。矩形代表模块或系统圆角矩形代表服务或操作菱形代表判断或路由圆柱代表数据库平行四边形代表数据或消息。这些默认语义不是谁规定的而是读者看多了之后形成的思维惯性。如果你用的形状和默认语义不一致读者就会困惑。比如用菱形表示一个普通服务别人会下意识觉得这是一个判断节点。线条同样有语义。实线代表确定的关系虚线代表弱关联或异步箭头代表数据流向或调用方向。最忌讳的是全图都用同一种带箭头的实线没有任何粗细和虚实变化读者只能靠猜。我的做法是主调用链路用粗实线异步/消息用细虚线配置关联用不带箭头的细实线这样一眼就能区分出不同类型的关系。4.4 字体与字号也是信息层级的一部分中文技术图里字体建议用系统默认的无衬线体比如苹方、微软雅黑、思源黑体代码块和接口名建议用等宽字体比如 JetBrains Mono、Consolas。字号至少分三档图标题最大比如 18~20px模块名次之14~16px注释和标签最小12px。小于 12px 的文字在投影或 PDF 导出时基本看不清尽量避免。同时注意模块名不要超过 6~8 个字。名字太长就换行或者精简否则框图看起来会非常笨重。接口名这类专业术语可以保留全称但要考虑是否需要做视觉降噪比如用灰色字体弱化。5. 实战从 0 到 1 设计一张系统架构图5.1 先用文本把结构列出来不要急着开画图工具大多数人画图的错误开头是打开工具拖一个框起个名字再拖一个框起个名字……画着画着发现布局不对又全部推翻。更高效的做法是先在文本编辑器或纸上把结构列出来。以“用户订单查询链路”为例我会先写下客户端App/Web ↓ 接入层API Gateway ↓ 订单服务 ├── 读缓存Redis ├── 查数据库MySQL 从库 └── 异步写日志Kafka → 日志服务 外围依赖用户服务账号校验、风控服务虚线关联这一步的价值在于结构在文字层面先得到确认进入画图阶段后只需要关心布局不再需要思考逻辑关系。文本结构列得越清楚画图越快。5.2 确定主视觉流向拿到文本结构后先确定主流向。大多数架构图适合“从上到下”或“从左到右”的流向。从上到下适合分层结构比如“接入层→业务层→数据层”从左到右适合链路结构比如“客户端→网关→服务→存储”。流向一旦确定整张图的阅读顺序就固定了读者不用上下左右来回找。我倾向于优先选“从上到下”因为和人们看文档的习惯一致。遇到特别长的链路再转成从左到右。5.3 从草稿到成图的细化过程第一步把核心链路的三四个模块先摆到画布上按主流向排好。先不急着连箭头把间距和对齐调好保证这几个模块在视觉上是一个整体。第二步加支撑模块。把缓存、消息队列、依赖服务放到核心链路的两侧用虚线或浅色连接。注意不要让支撑模块的连线穿到主链路的中间位置——保持核心链路区域尽量干净。第三步标注关键信息。比如在数据库模块上加“读写分离”、在消息队列模块上加“Topic 命名规范”用注释文本放在模块旁边而不是直接改模块标题。第四步处理异常路径。用统一的标号方式比如红色小圆圈数字标注重试、降级、熔断等行为在图底部或右侧放一个“备注”区域统一说明。5.4 成图之后的六个自检项画完之后我一般会按这个清单过一遍只看一眼秒回核心链路是哪个吗颜色语义同一种颜色是不是全程代表同一个含义线条语义实线、虚线、箭头有没有混用或误用文字可读导出 PNG 后最小字号贴到屏幕上还看得清吗边界清晰范围外的东西是不是都收进“外部系统”灰框了自洽完整图中引用的服务名、端口号、Topic 名和实际代码/配置对得上吗其中最后一条最容易被忽视。图里的服务名和代码里不一致是技术文档里非常低级但高频的错误。6. 画图过程中容易翻车的细节6.1 导出模糊分辨率和格式的坑画好的图要放进文档或PPT最常见的翻车是导出模糊。如果你用的是 Draw.io 或 Figma 这类矢量工具导出时优先选择 SVG 或较高倍率的 PNG。我的建议是导出 2x 甚至 3x 的 PNG或者直接嵌 SVG这样无论显示在手机还是高分辨率大屏上都不会虚。不要直接截图粘贴截图的清晰度取决于屏幕分辨率很容易糊。另一个坑是透明背景和白色背景。深色模式下透明背景的图显示会很好看但白底文档里带深色底的 SVG 反而会一团黑。建议在导出时确认一下目标文档的底色再决定导出配置。6.2 中文与特殊字符乱码Mermaid 和 PlantUML 这类代码生成工具处理中文时偶尔会出现乱码或排版异常。尤其是 PlantUML 依赖本地的字体渲染如果服务器或本地环境没有正确配置中文字体生成图片时中文就会变成方框。解决方案无非两条一是环境层面安装并配置好中文字体比如 Noto Sans CJK二是尽量减少图里的中文关键术语保留英文模块名用中文做辅助说明。还有一点某些工具对特殊字符如_、|、敏感文本里如果包含这类字符需要转义或改成全角写法否则解析时会断线。6.3 连线交叉与绕路版面乱的最大元凶连线交叉之后版面必乱这是所有画图人的共识。尤其架构图里模块一多连线就像蜘蛛网谁也看清。减少交叉的方法有几个一是把关系紧密的模块放在相邻位置长连线少交叉自然少二是利用“聚合线”或“总线条”多条同类关系合并成一条粗线到目标区域再分叉三是重新考虑布局方向从上到下太挤就换从左到右。如果必须交叉尽量让交叉点落在空白区域不要在模块上交叉。交叉点上加一个小圆弧或桥接符号能显著降低“线缠在一起”的错觉。6.4 图也要纳入版本管理很多团队文档仓库里只管代码图是散落在个人电脑里的在线草稿一换人全丢了。图如果用了代码生成工具直接随仓库维护就行改图等于改代码diff 一目了然。如果用了手动拖拽工具至少把源文件存到团队共享的云盘或 Git LFS 中同时导出一份 PDF 或 PNG 作为快照。我更推荐前者——代码生成工具有天然优势。7. 让图“活”起来组件库、图层与团队协作7.1 图层思维从“画一张图”到“管理整张图”复杂系统一张图画不下就要拆图层。不是绘图软件里的 Layer而是逻辑上的“视图层”。比如一个微服务架构可以拆成“部署视图”“调用视图”“数据视图”三张图。每一张图只讲一个维度读者可以按需查阅而不是面对一张超复杂总图。这个思路在 C4 model 里用得最系统我也在实际项目里验证过它的价值——画图的人好维护看的人好理解。7.2 团队组件库别再每个人各画各的团队里如果每个人都按自己的审美画图那文档仓库里的图风格会乱七八糟。有的用蓝底有的用绿底有的用圆角有的用直角读者跳着看会非常分裂。组件库也分代码型和视觉型两种。代码型组件库是把常见模块的文本模板沉淀下来比如“标准服务节点”“MySQL节点”“Redis节点”用的时候复制粘贴改名字就行。视觉型组件库是在 Figma 或 Draw.io 里定义好一套主色、字号、图形模板团队成员统一从这里拖。7.3 从静态图到交互原型进阶但不一定必要图做得好的人最后往往会想能不能做成可交互的架构图比如点击某个服务节点能看到它的详细指标。如果团队有精力这确实很酷。但我要泼一盆冷水交互图维护成本很高如果不是客户演示或高管驾驶舱这类强需求没必要一上来就做。先用好静态图把静态图的结构、规范、版本管理做到位性价比远高于追求交互。我在实际项目中见过太多团队卡在“把图做酷炫”上却连最基础的视觉一致性都没解决。先把基本功打牢再考虑炫技。我自己画了这几年图最大的感受是diagram-design 的本质不是“画得好看”而是“让人少费劲”。一张好的图能省掉一小时的会议讨论一张烂图能引发一整轮的口水战。每次画完图我都会问自己一句如果我是第一次看这张图的人我需要花多长才能看出它想说什么答案超过十秒就继续改。也希望你画的每一张图都能让别人觉得“这个系统我好像一下子就懂了”。
返回列表