用Mermaid画时序图

文章目录

时序图简介

时序图用于描述多个对象之间的交互过程,比如程序员下班就可以用下图表示:程序员按下电脑的关机键➡️电脑关机后,屏幕熄灭,被程序员看到➡️程序员离开。当然大部分程序员下班不关电脑就是了。
PC PC #mermaid-svg-l7aYqKEg9NWw5V6g{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-l7aYqKEg9NWw5V6g .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-l7aYqKEg9NWw5V6g .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-l7aYqKEg9NWw5V6g .error-icon{fill:#552222;}#mermaid-svg-l7aYqKEg9NWw5V6g .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-l7aYqKEg9NWw5V6g .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-l7aYqKEg9NWw5V6g .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-l7aYqKEg9NWw5V6g .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-l7aYqKEg9NWw5V6g .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-l7aYqKEg9NWw5V6g .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-l7aYqKEg9NWw5V6g .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-l7aYqKEg9NWw5V6g .marker{fill:#333333;stroke:#333333;}#mermaid-svg-l7aYqKEg9NWw5V6g .marker.cross{stroke:#333333;}#mermaid-svg-l7aYqKEg9NWw5V6g svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-l7aYqKEg9NWw5V6g p{margin:0;}#mermaid-svg-l7aYqKEg9NWw5V6g .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-l7aYqKEg9NWw5V6g text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-l7aYqKEg9NWw5V6g .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-l7aYqKEg9NWw5V6g .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-l7aYqKEg9NWw5V6g .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-l7aYqKEg9NWw5V6g .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-l7aYqKEg9NWw5V6g #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-l7aYqKEg9NWw5V6g .sequenceNumber{fill:white;}#mermaid-svg-l7aYqKEg9NWw5V6g #sequencenumber{fill:#333;}#mermaid-svg-l7aYqKEg9NWw5V6g #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-l7aYqKEg9NWw5V6g .messageText{fill:#333;stroke:none;}#mermaid-svg-l7aYqKEg9NWw5V6g .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-l7aYqKEg9NWw5V6g .labelText,#mermaid-svg-l7aYqKEg9NWw5V6g .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-l7aYqKEg9NWw5V6g .loopText,#mermaid-svg-l7aYqKEg9NWw5V6g .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-l7aYqKEg9NWw5V6g .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-l7aYqKEg9NWw5V6g .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-l7aYqKEg9NWw5V6g .noteText,#mermaid-svg-l7aYqKEg9NWw5V6g .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-l7aYqKEg9NWw5V6g .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-l7aYqKEg9NWw5V6g .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-l7aYqKEg9NWw5V6g .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-l7aYqKEg9NWw5V6g .actorPopupMenu{position:absolute;}#mermaid-svg-l7aYqKEg9NWw5V6g .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-l7aYqKEg9NWw5V6g .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-l7aYqKEg9NWw5V6g .actor-man circle,#mermaid-svg-l7aYqKEg9NWw5V6g line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-l7aYqKEg9NWw5V6g .actor-line{stroke-dasharray:5,5;}#mermaid-svg-l7aYqKEg9NWw5V6g :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Coder 关机 屏幕熄灭 明年见! Coder

上图虽小,但也表现出了时序图的诸多元素,其中最不可或缺的,就是贯穿Coder和PC这两个主要对象的两条竖线,此为生命线,自上而下延展成时间轴,严格表示时间的推移。

这个时序图的Mermaid源码如下

复制代码
%%{init: {'themeCSS': '.actor-line { stroke-dasharray: 5,5; }' }}%%
sequenceDiagram
    actor Coder
    Coder->>  PC:    关机
    PC   -->> Coder: 屏幕熄灭
    Coder -)  PC:    明年见!

这个代码的可读性是相当高的,最上方是时序图的声明【sequenceDiagram】,然后定义角色。图中共有两个对象,分别是程序员Coder和电脑PC,Coder被指定为actor,则被显示为一个火柴人,PC未作指示,默认是participant,表现为圆角矩形。

在做好定义后,就可以按照时间顺序,给出Coder和PC之间的交互过程了,每一条交互,格式都很一致,即A向B发送了一条信息,A->>B: msg,其中承载信息的箭头可以自行定制。

根据UML标准,生命线是虚线,但Mermaid默认为实线,所以在sequenceDiagram的头部,嵌入了初始化配置。

连接线

时序图中仅支持actor和participant两种节点,但是可通过@{"type":...}语法来指定具体的形状;支持实线和虚线两种连接线,每种又有不同的箭头格式如下表所示

无箭头 实心箭头 开放箭头 叉号
实线 -> ->> -) -x
虚线 --> -->> --) --x

根据UML标准,这些水平箭头用于表示消息的传递,具有明确的含义,如下表所示

语法符号 渲染效果 UML语义
->> 实线+实心箭头 同步消息
-->> 虚线+实心箭头 返回消息
-x 实线+叉号 异步消息
--x 虚线+叉号 异步返回;特殊信号
-> 实线+无箭头 一般依赖
--> 虚线+无箭头 注释;弱依赖

完整时序图

一个具备更多元素的时序图如下图所示。其中,服务端在接收到客户端的同步请求之后,被激活,其生命线上面出现了一个长条矩形。此外,在流程图进行的过程中,创建了新的对象【订单示例】。
订单实例 消息队列 数据库 服务端 客户端 订单实例 消息队列 数据库 服务端 客户端 #mermaid-svg-kcVzBJkkTCXSSND0{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kcVzBJkkTCXSSND0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kcVzBJkkTCXSSND0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kcVzBJkkTCXSSND0 .error-icon{fill:#552222;}#mermaid-svg-kcVzBJkkTCXSSND0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kcVzBJkkTCXSSND0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kcVzBJkkTCXSSND0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kcVzBJkkTCXSSND0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kcVzBJkkTCXSSND0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kcVzBJkkTCXSSND0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kcVzBJkkTCXSSND0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kcVzBJkkTCXSSND0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kcVzBJkkTCXSSND0 .marker.cross{stroke:#333333;}#mermaid-svg-kcVzBJkkTCXSSND0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kcVzBJkkTCXSSND0 p{margin:0;}#mermaid-svg-kcVzBJkkTCXSSND0 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kcVzBJkkTCXSSND0 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-kcVzBJkkTCXSSND0 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-kcVzBJkkTCXSSND0 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-kcVzBJkkTCXSSND0 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-kcVzBJkkTCXSSND0 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-kcVzBJkkTCXSSND0 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-kcVzBJkkTCXSSND0 .sequenceNumber{fill:white;}#mermaid-svg-kcVzBJkkTCXSSND0 #sequencenumber{fill:#333;}#mermaid-svg-kcVzBJkkTCXSSND0 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-kcVzBJkkTCXSSND0 .messageText{fill:#333;stroke:none;}#mermaid-svg-kcVzBJkkTCXSSND0 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kcVzBJkkTCXSSND0 .labelText,#mermaid-svg-kcVzBJkkTCXSSND0 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-kcVzBJkkTCXSSND0 .loopText,#mermaid-svg-kcVzBJkkTCXSSND0 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-kcVzBJkkTCXSSND0 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-kcVzBJkkTCXSSND0 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-kcVzBJkkTCXSSND0 .noteText,#mermaid-svg-kcVzBJkkTCXSSND0 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-kcVzBJkkTCXSSND0 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kcVzBJkkTCXSSND0 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kcVzBJkkTCXSSND0 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-kcVzBJkkTCXSSND0 .actorPopupMenu{position:absolute;}#mermaid-svg-kcVzBJkkTCXSSND0 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-kcVzBJkkTCXSSND0 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-kcVzBJkkTCXSSND0 .actor-man circle,#mermaid-svg-kcVzBJkkTCXSSND0 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-kcVzBJkkTCXSSND0 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 1. 提交订单 (同步请求) 1 2. 参数校验 (内部方法) 2 3. 生成订单数据 3 4. 发送异步通知 (非阻塞) 4 5. 保存订单 5 6. 返回保存成功 (虚线实心箭头) 6 7. 清理临时订单实例 7 8. 返回下单结果 8

代码以及注释如下

复制代码
sequenceDiagram
    autonumber
    participant Client as 客户端
    participant Server as 服务端
    participant DB as 数据库
    participant MQ as 消息队列

    %% 1. 同步消息 (实线实心箭头)
    Client->>Server: 1. 提交订单 (同步请求)
    
    %% 激活期
    activate Server
    
    %% 2. 自调用 (折返箭头)
    Server->>Server: 2. 参数校验 (内部方法)
    
    %% 3. 创建对象 (create 关键字)
    create participant Order as 订单实例
    Server->>Order: 3. 生成订单数据
    
    %% 4. 异步消息 (实线叉号)
    Server-xMQ: 4. 发送异步通知 (非阻塞)
    
    %% 5. 同步消息 (跨多个对象)
    Server->>DB: 5. 保存订单
    DB-->>Server: 6. 返回保存成功 (虚线实心箭头)
    
    %% 6. 销毁对象 (destroy 关键字 + 叉号)
    destroy Order
    Server--xOrder: 7. 清理临时订单实例
    
    %% 7. 返回消息 (虚线实心箭头)
    Server-->>Client: 8. 返回下单结果
    
    %% 结束激活期
    deactivate Server
相关推荐
倔强的石头1064 小时前
应用账号最小权限实践:读写账号、报表账号、运维账号分层
java·运维·开发语言
Android系统攻城狮5 小时前
Linux Gstreamer深度解析之gst_audio_encoder_get_frame_samples_min调用流程与实战(六十)
linux·运维·服务器·音视频·gstreamer音视频·音视频进阶·gstreamer音视频进阶
_upupup6 小时前
Linux中的自动化构建——make/Makefile
linux·运维·自动化
还卿一钵无情泪7 小时前
Docker 部署Unsloth 绕开环境配置难题
运维·人工智能·docker·ai·容器·nlp·干货
打工仔折腾 AI8 小时前
Docker镜像分层与卷挂载到底怎么工作:一次文件系统层面的实测分析
运维·人工智能·后端·python·docker·容器·性能优化
大猫会长8 小时前
调用codebuddy集成的supabase授权白屏解决方法
linux·运维·服务器
夜之眷属9 小时前
服务器被挖矿病毒入侵的排查与清理实录
运维·服务器
极客先躯9 小时前
高级java每日一道面试题-2026年01月20日-实战篇[Docker]-如何实现镜像的跨区域复制?
java·运维·docker·容器·架构图
韩振方9 小时前
为什么服务显示占了 8G,实际内存却没那么多?
运维
xixiaoyunya10 小时前
虚拟机备份怎么做:镜像级与文件级搭配的完整实操方案
linux·运维·网络