Skip to content Skip to footer

时序图怎么画?UML 时序图 6 步画法(含检查清单与反例)

先给你一套能直接照着做的答案:时序图 = “参与者 + 消息 + 约束”

很多人卡在“时序图怎么画”,不是因为不会画箭头,而是没有把问题拆开。

一张能交付的时序图(UML 序列图)至少回答三件事:

参与者是谁:谁在这个交互里出现?边界在哪里?(前端/网关/服务/外部系统/人)

消息发生了什么:谁先调用谁?同步还是异步?返回值要不要画?

约束与分支是什么:条件(if/else)、可选、循环、并发、超时重试、回调、补偿、幂等等怎么表达?

如果你只画了“主流程的一串箭头”,那通常不叫交付级时序图,只能算“示意图”。交付级时序图要能支撑:

研发:接口边界、调用顺序、异常策略

测试:mock 点、异常注入点、覆盖路径

架构:跨服务耦合、链路长度、同步/异步设计是否合理

产品/文档:把需求从“描述”变成“可执行”的协作材料

下面这 6 步是我最推荐的一套落地流程:从一段文字/PRD 里把时序图画到“能评审、能验收”。

想快一点把文字交互变成规范图,也可以用在线工具边写边看效果:手打时序图 - 时序图在线制作

第 1 步:把“叙述性文字”改写成“交互脚本”(别急着画)

画时序图之前,先做一个动作:把需求段落改写成逐条交互脚本。

1)把“描述”拆成“句式固定”的脚本

把每句话统一成这种结构:

[参与者A] → [参与者B]:做什么(请求)

[参与者B] → [参与者A]:返回什么(响应)

条件/约束:在什么情况下发生

举个常见例子(登录 + 短信验证码):

用户 → 前端:输入手机号并点击获取验证码

前端 → 认证服务:请求发送短信验证码(手机号)

认证服务 → 短信网关:发送短信

短信网关 → 认证服务:返回发送成功/失败

认证服务 → 前端:返回“已发送”或错误码

用户 → 前端:输入验证码并提交

前端 → 认证服务:校验验证码

认证服务 → 用户中心:查用户状态(是否冻结/是否新用户)

认证服务 → 前端:返回 token/登录失败原因

你会发现:脚本一写出来,图已经在脑子里了。

2)在脚本里先标注“你必须交代的坑”

建议在脚本旁边用括号先打标(后面要画成片段):

(分支)验证码错误 / 过期 / 超次数

(重试)短信网关失败重试 1 次

(风控)命中风控时走人工校验

(异步)短信发送是异步回执还是同步返回

别怕啰嗦。时序图的价值就在这些“坑”里。

第 2 步:定参与者与边界(生命线别乱放)

你要先回答:这张图的“系统边界”是什么?

交付时序图最容易翻车的地方是:参与者摆放含糊。

一个实用原则:

你负责的系统/服务放在中间

**上游(调用你)**放左边

**下游(你调用的外部/其他服务)**放右边

并且给参与者起“可定位”的名字:

✅ Web 前端、API Gateway、Auth Service、SMS Provider、User Service

❌ 系统、后台、服务端(太笼统,后续会扯皮)

生命线(Lifeline)怎么命名才不尴尬

建议使用:实例/角色 + 类型 的方式,尤其是你在画模块级或服务级交互时。

client: WebApp

gw: APIGateway

auth: AuthService

sms: SmsProvider

这样后续你加“自调用”“并行片段”都不会糊。

反例:把数据库当参与者、把“缓存”当主角

不是说 DB/Redis 不能画,而是要问:这张图的核心问题是“跨参与者交互”还是“内部实现细节”?

如果你在讲“接口对接、回调、重试、幂等”,DB 通常不必出现。

如果你在讲“写库先后、事务边界、最终一致性方案”,那 DB/缓存可以出现,但要把它们当“被调用者”,并标注清楚一致性语义。

一句话:先确定沟通对象是谁,再决定参与者粒度。

第 3 步:画“主干消息”——只画 30% 的内容

现在才开始画箭头。

1)先只画主干(Happy Path),不要一上来就塞分支

从脚本里挑最稳定的一条路径:

请求:谁 → 谁

同步返回:谁 → 谁

先让评审者看懂“到底是谁在跟谁说话”。

2)把消息写成“接口级语言”,别写成“动作口号”

✅ POST /auth/sms/send、verifyCode(phone, code)、createOrder()

❌ 进行校验、处理业务、执行逻辑

你不用写到每个字段,但至少要把意图 + 关键参数写出来:

sendSms(phone, scene)(scene 很关键:登录/注册/找回密码)

verifyCode(phone, code, scene)

3)同步/异步先定清楚:箭头类型别乱

如果你画 UML,至少要区分:

同步消息:调用方等待返回(常见为实线 + 实心箭头)

异步消息:调用方不等待(常见为实线 + 空心箭头)

返回消息:虚线返回(可画可不画,但要一致)

实务上,一个判断标准很好用:

“调用方会不会阻塞等待结果?”——会:同步;不会:异步。

小技巧:在工具里画的时候,先把消息类型选对。比如在编辑器左侧点选“消息类型”(同步/异步/返回),右侧实时预览能立刻看到箭头样式变化,避免画到一半才发现风格不统一。

第 4 步:把“坑”补成组合片段(alt/opt/loop/par)

时序图专业不专业,往往就看你会不会用组合片段。

先记住:片段不是为了好看,是为了“无歧义”

当读者看到一段消息时,他必须知道:

这是必走还是可选?

这是分支还是循环?

这是并发还是“看起来分叉”?

对应的片段:

alt:分支(if/else)

opt:可选(if)

loop:循环(for/while/重试)

par:并行(同时发生)

反例 1:用两条箭头表示 if/else,但没写条件

很多人这样画:

认证服务 → 前端:成功

认证服务 → 前端:失败

读者会问:什么时候成功?什么时候失败?条件在哪?

修正:用 alt,每个分支写 guard 条件。

[code valid] 返回 token

[code invalid] 返回 error

反例 2:把重试画成“重复三次消息”,但没有重试策略

重试不是“重复画几条箭头”。你至少要交代:

谁重试(调用方?中间层?SDK?)

重试次数/间隔

是否幂等

超过次数后怎么处理(降级/失败/补偿)

修正:用 loop,并在循环标题里写策略。

loop retry <= 2, backoff=200ms

反例 3:并发画成“从一个点分叉出去”,但实际不是并发

如果只是“先做 A 再做 B”,那不是并发。

修正:只有确实同时发生、互不等待时,才用 par。

例如下单后:

订单服务并行发起:

发消息给营销(埋点/优惠)

发消息给风控(异步审核)

并行片段能提醒研发/测试:这两条链路的失败策略可能不同。

第 5 步:把“可交付细节”补齐:激活条、返回消息、边界条件

主干 + 分支之后,你还差最后一口气:把图补到“别人照着就能做”。

1)激活条(Activation)画多长?

别把激活条当装饰。

同步调用:激活条通常覆盖“从发起请求到收到返回”的时间窗口。

异步消息:发送后调用方不等返回,激活条不应该一直拉长。

一个常见修正:

你画了“异步投递 MQ”,却把调用方激活条拉到“消费完成”——这会误导读者以为是同步阻塞。

2)返回消息要不要画?

建议用一个标准:

如果返回值对后续分支有影响(成功/失败、错误码、状态),画。

如果返回值只是“OK”且不影响后续,可以不画,但要在图中保持一致风格。

交付时最怕:一半消息画返回,一半不画。读者会以为你漏了。

3)边界条件:至少补齐这 6 类

在时序图里,“边界条件”不是可选项。建议至少补齐:

参数校验失败(空值/格式/签名)

权限/鉴权失败(token 失效、角色不足)

资源不存在/状态不允许(订单已取消还支付?)

超时(上游等待多久?下游超时怎么算?)

重试/幂等(重复请求如何处理)

外部依赖异常(第三方不可用、回调延迟)

这些通常用 alt/opt/loop + 注释(note)表达。

如果你经常需要补这些边界,用“边写边预览”的方式会快很多:左侧编辑器里点选生命线、消息、组合片段(alt/opt/loop/par),右侧实时预览能即时看到结构是否闭合;并且自动排版会把片段对齐,避免你在对齐上浪费时间。

第 6 步:做一次“交付前验收”:检查清单 + 读者视角走读

画完以后不要急着发。

交付检查清单(建议复制到评审评论里)

参与者与边界

参与者命名可定位(不是“系统/后台”)

图的边界明确(这张图解决哪个范围的问题)

参与者粒度一致(不要一边是“订单服务”,一边是“数据库表”)

消息与顺序

每条消息写的是“接口意图 + 关键参数/关键返回”

同步/异步箭头类型一致且符合语义

顺序的关键点(先后会影响结果的点)在图里能看出来

分支与异常

分支用 alt,且每个分支都有 guard 条件

可选用 opt,循环/重试用 loop

至少覆盖:校验失败/鉴权失败/状态不允许/超时/重试幂等/外部依赖异常

可读性与可维护

一屏能读懂主干(必要时拆多张图)

复杂片段有注释(note),说明策略而不是堆箭头

图的风格统一(是否画返回消息、是否画激活条)

读者视角走读(30 秒自测)

把自己当成“第一次接手这个需求的同事”,从上到下读一遍:

我能在 10 秒内说清“谁跟谁交互、解决什么问题”吗?

我能指出“失败/超时/重试”发生在哪里吗?

我能根据图写出至少 5 条测试用例吗?

如果做不到,说明你还缺关键信息,别急着优化排版。

两个典型场景:用 6 步快速拆解(让你有参照物)

下面用两个高频场景,示范怎么从文字到可交付时序图。

场景 A:登录(验证码 + 失败重试 + 风控)

交互脚本提炼(第 1 步)

Web 前端 → AuthService:sendSms(phone, scene=login)

AuthService → SmsProvider:send(phone, template)

SmsProvider → AuthService:accepted | rejected

Web 前端 → AuthService:verifyCode(phone, code, scene=login)

AuthService → RiskService:check(phone, device, ip)

AuthService → UserService:getUser(phone)

AuthService → Web 前端:返回 token 或错误

关键坑(第 4/5 步要画出来)

alt:验证码正确/错误/过期/超次数

opt:命中风控 → 触发二次校验/人工验证

loop:SmsProvider 发送失败重试(次数/间隔)

note:错误码约定(给前端提示与埋点)

测试同学最在意的点

风控超时怎么办?默认放行还是默认拒绝?(这必须在图里体现)

重试是否会导致短信重复发送?如何幂等?

场景 B:下单-支付-回调(同步/异步、超时、补偿)

这个场景非常适合用时序图,因为它天然包含:

同步下单

异步支付回调

重复回调(幂等)

超时未支付的关单补偿

参与者建议(第 2 步)

client: WebApp

gw: APIGateway

order: OrderService

pay: PayService

third: ThirdPay

mq: MessageQueue(如果你确实用事件驱动)

必须画出来的片段(第 4/5 步)

alt:库存不足/价格变更/风控拒绝

par:创建订单后并行触发通知/风控异步

loop:第三方回调重试(可能 3~10 次)

alt:回调签名合法/非法

opt:重复回调(幂等命中)

opt:超时关单补偿(谁触发、何时触发)

这种图画清楚之后,研发能据此实现幂等;测试也能直接拿来设计“重复回调、乱序回调、延迟回调”的用例。

常见问题 FAQ(把你画图时最容易纠结的点一次解决)

Q1:一张时序图画多细才合适?

看你的交付目的。

需求评审:到“参与者 + 关键消息 + 关键分支/异常”即可

技术方案评审:需要补齐“超时、重试、幂等、补偿、协议约定”

测试用例评审:需要能从图上直接拆出用例路径(主干 + 关键异常)

实操建议:

超过一屏读不完,就拆成 2~3 张:主干一张,异常/回调一张,补偿/关单一张。

Q2:返回消息到底要不要画?

用“是否影响分支”来决定,并保持一致。

影响后续决策:画,并写出关键返回(错误码/状态)

不影响决策:可不画,但别一半画一半不画

Q3:要不要把数据库/缓存/内部函数调用画进来?

多数情况下不需要。

你在沟通“跨服务交互” → 不画 DB

你在沟通“事务边界、写库顺序、最终一致性” → 可以画,但要配注释说明一致性语义

时序图不是代码调用栈。把粒度画到“让人能协作”即可。

Q4:时序图能替代接口文档吗?

不能替代,但能显著减少接口文档的“误读”。

接口文档:字段、约束、示例

时序图:顺序、分支、异常、谁负责

最理想的组合是:一张时序图 + 关键接口文档链接/简要说明。

Q5:我不会 UML 标准符号,会不会画错?

你不需要把 UML 当考试。

最低要求是:

参与者/生命线清晰

同步/异步不混

分支/循环/并发不歧义

符号细节可以逐步规范化。最怕的是“看起来像 UML,但语义全靠猜”。

给你一个“反例 → 修正”的快速对照(用来补字也用来补质量)

下面这些是我在评审里最常见的“看起来画了,但不专业”的问题,以及对应修正方式。

反例 1:把“失败处理”写成一句话

反例:支付失败 -> 提示用户

问题:失败原因很多,处理策略也不同。

修正:拆成 alt 并写 guard:

[余额不足] 返回提示 + 保留订单

[签名校验失败] 记录安全日志 + 告警

[超时] 触发查询/补偿 + 前端提示“处理中”

反例 2:没有标注谁负责重试

反例:第三方支付回调失败 -> 重试

问题:第三方重试?我方重试?MQ 重试?策略不同。

修正:在 loop 或 note 里写清楚:

loop third retry up to 8, interval=5s/30s/5m

我方收到回调后:verifySign() 失败不重试、直接拒绝;业务处理失败返回 200 还是 500?(这也要在图里体现)

反例 3:把“并行”当“顺序”画

反例:订单服务先调用营销再调用风控,读者会以为必须按顺序

修正:用 par:营销与风控并行,互不阻塞。

反例 4:缺少“幂等”表达

反例:回调到达两次,图里看不出系统怎么处理

修正:用 opt 或 alt:

[idempotent hit] 直接返回成功(或返回已处理)

[first time] 更新订单状态 + 发消息

最后给一个轻量建议:用“文字 → 图”的闭环减少返工

如果你的团队经常在“文字描述”和“图”之间来回改,建议建立一个闭环:

先用第 1 步把文字写成脚本(这本身就是需求澄清)

用编辑器快速点选生命线/消息/组合片段,把脚本落成图

右侧实时预览检查结构是否闭合、分支是否有 guard

导出交付格式(SVG/PNG/JPEG 便于评审;需要工程化协作时导出 draw.io)

这样你会发现:画图不再是“美术活”,而是一种把协作语言变得无歧义的过程。

如果你想把这套流程跑得更快,可以直接用这个工具把脚本落成图并自动排版:

在线生成与编辑:手打时序图 - 时序图在线制作

支持导出:SVG/PNG/JPEG/draw.io(方便贴文档、贴 PR、贴评审)

也可以让 AI 先根据你的“交互脚本”生成初稿,再由你补齐分支/异常

你可以直接复用的“6 步模板”(复制粘贴用)

最后附一个你可以复制到文档里的模板,写完再画:

目标与范围:这张图要解释什么?不解释什么?

参与者:A(上游)、B(我方)、C(下游/外部)……

主干交互(Happy Path):

A → B:……

B → C:……

C → B:……

B → A:……

关键分支(alt/opt):

[条件1] ……

[条件2] ……

循环/重试/并发(loop/par):

loop:次数/间隔/幂等

par:并行任务及失败策略

边界条件与验收:超时、异常、补偿、幂等、测试用例路径

把模板填完,你基本就不会“画不出来”。

Copyright © 2088 世界杯射手榜_2014世界杯16强对阵表 - panlongs.com All Rights Reserved.
友情链接