时序图是什么?(UML 序列图)3 分钟搞懂:适用场景、核心元素、常见误解
时序图(Sequence Diagram)是用“时间顺序”把对象之间的交互消息画出来的 UML 图。本文用最短路径讲清:时序图适合解决什么问题、有哪些核心元素、最常见的误解是什么,以及如何快速画出可交付版本。
很多人第一次听到“时序图/序列图”,脑子里会冒出两个疑问:
- 我已经会画流程图了,为什么还要学时序图?
- 时序图到底要画到多细?是不是要把每个函数调用都画出来?
结论先说在前面:时序图不是用来画“步骤”,而是用来画“交互”。当你想把“谁先调用谁、调用的顺序如何、哪里会等待返回、哪里会异步回调、失败时怎么走”讲清楚时,时序图比流程图更合适。
如果你想边看边画,或者把一段文字交互快速变成专业、美观、可导出的时序图,你可以用这个在线工具(支持自动排版、实时预览、导出 SVG/PNG/JPEG/draw.io,也支持 AI 生成):
下面用“3分钟能看懂”的方式,把时序图讲清楚。
1)时序图是什么?一句话定义
时序图(Sequence Diagram),也叫序列图,是 UML 的一种交互图,用来描述多个对象(参与者)之间按时间顺序发生的消息交互。
你可以把它理解成:
- 横向:有哪些参与者(用户、客户端、服务端、数据库、第三方服务、消息队列……)
- 纵向:时间从上往下走
- 箭头:谁给谁发了什么消息(同步/异步/返回)
它的价值不是“把流程画出来”,而是把交互的顺序、等待关系、分支与异常画清楚。
2)时序图最适合解决什么问题?(5 个典型场景)
下面这些场景,如果你只用流程图描述,往往会越画越别扭;换成时序图,反而一眼清楚。
场景 A:登录/注册(验证码、风控、失败重试)
登录流程看起来是“步骤”,但真正容易出问题的是交互:
- 前端什么时候发请求?
- 服务端什么时候查库?
- 是否要调用风控服务?
- 失败后是返回错误还是触发二次校验?
这些在时序图里更好表达。
场景 B:下单-支付-回调(同步 + 异步混合)
支付系统典型特点:
- 下单通常是同步请求
- 支付结果往往通过异步回调通知
- 回调可能重复、可能延迟
如果你不把同步/异步、等待/不等待画出来,评审时一定会吵。
场景 C:接口调用链路(超时、重试、降级、熔断)
研发同学写“接口时序图”,通常不是为了好看,而是为了:
- 对齐调用顺序
- 标出超时点
- 说明重试策略
- 解释失败时如何兜底
场景 D:回调/Webhook(签名校验、幂等、补偿)
回调类流程最容易出线上事故:重复回调、顺序不一致、签名不对、幂等没做好。时序图能把这些关键判断点固定下来。
场景 E:多人协作的技术文档/评审交付
当你要把方案交付给别的团队,或者写进文档/PPT 时:
- 流程图更像“业务步骤”
- 时序图更像“接口与交互合同”
这两者不是互斥,而是各自负责不同层面的清晰。
3)时序图的核心元素有哪些?(别背全套,先掌握 6 个就够)
很多人觉得时序图难,是因为一上来就被 UML 名词吓到。其实入门只要先掌握 6 个概念。
3.1 参与者(Actor / Participant)
参与者可以是人(用户/管理员),也可以是系统组件(前端、服务、数据库、第三方)。
经验:参与者不要贪多。 如果你为了“完整”把每个内部模块都画上,图会变成毛线团。
一个可操作的标准:
- 评审级:参与者保持在 4–7 个
- 研发链路级:可以更多,但要拆图
3.2 生命线(Lifeline)
每个参与者下面那条竖虚线就是生命线,表示它在这段交互里“存在”。
很多人的误区是把生命线当成“线程/进程”,然后开始纠结长度。入门阶段你只要记住:生命线主要用于承载消息箭头和激活条。
3.3 消息(Message):同步、异步、返回
这是时序图的灵魂。
- 同步消息:发送方发出后要等结果(常见:HTTP/RPC调用)
- 异步消息:发送方发出后不等待(常见:消息队列、事件通知)
- 返回消息:接收方处理完返回结果(不一定每次都要画,后面会讲)
画图时最重要的是:你要让读者看出“有没有等待”。
3.4 激活条(Activation)
生命线上的细长矩形表示“正在执行/占用”的时间段。
激活条不一定要画得很细,但它在两类场景非常有价值:
- 你要表达“谁在等待谁”
- 你要表达“嵌套调用”(例如服务 A 调用服务 B,B 又调用 C)
3.5 自调用(Self-call)
一个参与者调用自己,常用于表达:内部方法调用、递归、内部处理。
注意:自调用不是用来替代流程图的。如果你把所有内部步骤都画成自调用,时序图会失去重点。
3.6 组合片段(Combined Fragment):alt/opt/loop/par
这是让时序图从“线性对话”升级成“可表达真实世界”的关键。
- alt:分支(if-else)
- opt:可选分支(if 条件成立才发生)
- loop:循环(重试、分页、重复请求)
- par:并行(要谨慎使用,容易误导)
如果你只会画主干,不会画分支,那么你的时序图往往“看起来对,但不能交付”。
4)最常见的 6 个误解(把这些避开,你的时序图会立刻变专业)
误解 1:时序图 = 流程图
流程图回答“先做什么再做什么”,时序图回答“谁先调用谁”。
当你关心的是“交互合同”(接口、回调、等待、异常)时,优先画时序图。
误解 2:时序图要画到“每个函数”
大多数情况下不需要。
更实用的做法是:
- 先画到“服务/系统/外部依赖”层级
- 真正复杂的一段再单独拆出子图
误解 3:返回消息必须每条都画
如果每个同步调用都画返回,你的图会立刻变长、变乱。
返回消息建议只在两种情况画:
- 返回值影响后续分支(例如:校验通过/失败)
- 你要表达性能/等待关系(例如:超时点)
误解 4:分支只要写“成功/失败”就够了
这会让读者不知道失败后怎么办。
更可交付的做法是把失败按原因拆 2–3 类(例如:参数非法/无权限/超时),让每条分支都有信息量。
误解 5:并行用 par 随便画
par 表示并行执行,但很多业务上的“看起来同时”其实是:
- 异步事件(用异步消息更合适)
- 或者只是“先后顺序不重要”(可以用注释,不一定要 par)
误解 6:对象命名随意
评审时最常见的扯皮之一就是:同一个东西在图里被叫了三个名字。
建议:
- 参与者命名尽量统一为“角色/系统名”
- 消息命名尽量用“动词+对象”(例如:查询订单、校验签名、创建支付单)
5)如何快速画出一张“可交付”的时序图?(不靠手动排版)
如果你现在要把一段交互写进文档或做评审,建议用下面这个“最小可交付”流程:
- 先确定 4–7 个参与者(别贪多)
- 先画主干消息(只画关键交互)
- 把关键分支用 alt/opt/loop 表达出来(不要只写成功/失败)
- 再决定哪些返回消息需要画(影响分支的才画)
- 最后导出:
- 写文档/论文:优先 SVG(放大不糊)
- PPT/截图:高清 PNG/JPEG
- 交给同事继续编辑:导出 draw.io
如果你想用“点一点 + 输入文本”就把这些做完,并且自动排版、右侧实时预览,可以直接打开:
FAQ
Q1:时序图、序列图、UML时序图是不是同一个东西?
大多数情况下可以当作同一个概念使用。更严格的说法是:时序图/序列图是图的类型,UML 是规范体系;当你按 UML 语义画(消息类型、片段语义更规范)时,就可以叫 UML 时序图。
Q2:参与者里要不要画数据库?
看你的目的:
- 评审业务/接口:画到“服务”层就够了,数据库可以省略
- 你要表达一致性、事务、补偿:数据库/缓存/消息队列就应该出现
Q3:我应该先画时序图还是先画流程图?
如果你在梳理业务步骤,先画流程图;如果你在梳理系统交互与接口合同,先画时序图。
很多高质量文档会两张都画:流程图讲步骤,时序图讲交互。
6)一个“真实可评审”的小案例:用户登录(含验证码与风控)该怎么画?
很多教程讲时序图会停在“概念层”,但真正让评审不扯皮的,是你能不能把关键交互和分支画出来。
下面用“登录”举一个更贴近真实系统的拆解。你不需要照抄这套流程,重点是看它如何把同步/异步、分支条件、失败处理表达清楚。
6.1 参与者怎么选(别一上来就画 10 个)
建议先选到“能说清楚责任边界”的层级:
- 用户(或客户端)
- 前端(Web/App)
- 认证服务(Auth)
- 风控服务(Risk)
- 用户服务/用户库(User)
- 短信服务(SMS)
如果你只是做作业/写概要文档,也可以把 User+DB 合并成一个“用户系统”。
6.2 主干交互(先把大链路跑通)
主干消息可以按这个顺序组织:
- 用户 → 前端:输入手机号
- 前端 → Auth:请求发送验证码
- Auth → Risk:检查频控/黑名单
- Risk → Auth:允许/拒绝
- Auth → SMS:发送验证码
- SMS → Auth:发送结果(可选画返回)
- 用户 → 前端:输入验证码
- 前端 → Auth:提交验证码
- Auth → User:校验用户/创建登录态
- Auth → 前端:返回 token/会话
这段里至少要把“Risk 检查”画出来,否则登录图会显得过于理想化。
6.3 必画的分支(否则“成功/失败”毫无信息量)
建议用组合片段把分支按“读者关心”组织,而不是按“程序分支”组织。
分支 A:风控拒绝(alt)
- 条件示例:命中黑名单 / 频控触发 / 设备指纹异常
- 后续处理:提示稍后再试 / 触发图形验证码 / 转人工
分支 B:短信发送失败(alt)
- 条件示例:运营商通道异常 / 配额不足 / 参数不合法
- 后续处理:提示失败 + 允许重发(loop)
分支 C:验证码错误/过期(alt + loop)
- 错误:允许重输,但要限制次数
- 过期:要求重新发送
为什么要把“错误”和“过期”分开?因为它们对用户体验与风控策略不同。
6.4 重试(loop)要写什么才算可交付?
很多人画 loop 只写“重试”,但评审时会被追问:
- 重试几次?
- 触发条件是什么?
- 间隔多久?
你不必写到实现细节,但至少给一个可评审的边界,例如:
- 仅对“短信通道异常/网络超时”重试
- 最多 3 次
- 60 秒内超过次数触发图形验证码
把这些写在 loop 的标签里,图就从“概念图”变成“能落地的方案图”。
7)导出与交付:SVG / PNG / draw.io 分别什么时候用?
你工具支持导出 SVG、PNG/JPEG、draw.io,这一点对“把图放进文档/PPT/交接”非常关键。
7.1 导出 SVG:适合文档与论文(放大不糊)
如果你的时序图会被放进:
- 技术文档(Markdown/网页)
- 论文/报告
- 需要多次缩放的场景
优先选 SVG。
7.2 导出 PNG/JPEG:适合 PPT 与截图
PPT 里最常见的问题是“放大后发虚”。解决思路不是换格式,而是:
- 导出更高分辨率
- 控制单张图的信息量(复杂就拆图)
7.3 导出 draw.io:适合交接与二次编辑
如果你要把图交给同事继续改,或者后续还会频繁调整布局,导出 draw.io 会更省时间。
你可以把它当作“交付源文件”,而不是只交付一张图片。
8)再强调一次:时序图画得好,关键是“分支与异常”
很多人画时序图只画主干,最后在图旁边写一行“失败则返回错误”。这几乎等于没画。
你可以用一个很简单的自检:
- 这张图里有没有明确的 alt/opt/loop?
- 失败分支是不是有“下一步动作”(提示/重试/转人工/补偿)?
- 是否能据此写出 5 条测试用例?
如果答案都是“能”,这张图基本就能拿去评审。
想把一段文字交互快速落到图上(不手动排版、点选生命线/消息/片段、右侧实时预览),可以直接打开:
9)常见问法速答:你可能会搜的 12 个问题
为了让你在查资料时少走弯路,这里把“新手最常搜、最常问”的问题集中回答一下。
Q1:时序图一定要画激活条吗?
不一定。
- 如果你只是在对齐“谁调用谁”的顺序,可以不画激活条。
- 如果你要表达等待关系、嵌套调用、性能瓶颈,激活条会非常有用。
一个简单判断:你是否需要解释“谁在等谁”? 需要就画。
Q2:参与者该用“用户/前端/后端”,还是用“具体服务名”?
取决于读者是谁:
- 面向业务/产品评审:用“前端/订单服务/支付服务”这种可理解的名字
- 面向研发实现:用“OrderService/PayGateway/InventoryService”更直接
但无论哪种,最重要的是:同一张图里不要一会儿“支付系统”,一会儿“PaySrv”,会让读者以为是两个东西。
Q3:消息命名有什么规范?
推荐“动词 + 对象”或“动作 + 结果”的写法:
- 创建订单
- 查询库存
- 校验签名
- 更新支付状态
不推荐“请求/处理/调用”这种空词。
Q4:返回消息到底画不画?
只在两种场景强烈建议画:
- 返回值会影响分支(通过/失败)
- 你要强调等待与耗时(例如:超时点)
其他情况可以省略,让图更干净。
Q5:时序图里要不要画缓存/消息队列?
如果它会影响交互语义(异步、延迟、重试、至少一次投递),就应该画。
- MQ 不画出来,读者会误以为是同步调用
- 缓存不画出来,读者会误以为每次都查库
Q6:组合片段 alt/opt/loop/par 的条件写在哪里?
条件应该写在片段的标签里(例如 alt 的每个分支条件)。
条件的写法尽量“可验证”,不要写情绪词:
- 推荐:token 已过期 / 签名校验失败 / 库存不足
- 不推荐:异常 / 不对 / 有问题
Q7:loop(循环)怎么写才不空泛?
loop 最容易被追问“循环几次”。
建议你至少写三件事中的两件:
- 次数上限(最多 3 次)
- 触发条件(仅超时/5xx 重试)
- 间隔策略(指数退避)
这样才算“可交付”。
Q8:par(并行)是不是很常用?
par 很容易误导读者以为“严格并行”。
在很多业务系统里,并行更多是“异步事件”或“顺序不重要”。如果你不确定,优先用异步消息表达,而不是 par。
Q9:时序图能不能画“业务规则”?
可以,但不要把时序图写成规则百科。
更好的做法是:
- 规则用条件(alt/opt)表达
- 规则的详细定义写在旁注或文档里
Q10:时序图怎么保证不画错?
用一个非常实用的自检方法:
- 把图当成“对话记录”,从上往下读一遍
- 看看有没有一句话读不通(例如消息缺主语、返回缺来源)
- 看看有没有“没有下一步动作”的分支
Q11:时序图和接口文档(API 文档)是什么关系?
时序图不是接口文档的替代品,但它能把“接口之间的顺序与依赖”讲清楚。
- 接口文档回答:字段/错误码/参数
- 时序图回答:谁先调用谁、失败怎么走、回调怎么处理
Q12:我想快速画,最省时间的方式是什么?
先把参与者和主干消息列出来,再补 2–3 条最关键的异常分支,然后用工具自动排版。
你可以直接用在线编辑器点选生命线/消息/组合片段,右侧实时预览,最后一键导出 SVG/PNG/draw.io: