← 返回编辑器 所有教程
EN

如何用 Mermaid 画架构图

架构图用于展示系统组件、分组和它们之间的连接关系,适合系统设计、架构评审、技术文档。Mermaid 用 architecture-beta 声明架构图,核心是 group(分组)和 service(服务),加上强制指定方向的连线。

为什么用架构图?

适用场景

适合

不适合

与其他图表对比

图表类型 核心用途 与架构图的区别
架构图 带图标的小规模云/系统拓扑 有云图标,但布局控制非常有限
流程图 流程与决策,通用结构展示 没有内置图标,但布局控制成熟(directionsubgraph),大规模下更可靠

选择建议:如果想要云风格图标,且系统规模小、连接大致是线性的,用架构图。如果组件超过 8 个、有多处汇入汇出,或者需要精确控制布局,改用流程图。

声明图表

architecture-beta
    group sys(cloud)["我的系统"]

在 MermZen 中试试 →

group 是一个带标签的容器:group id(icon)[标题]。内置图标只有 5 个:clouddatabasediskinternetserver——这就是全部,没有办法接入自定义图标(比如某个云厂商的 logo),除非做完整的 JS 集成(多数用户用不到)。

注意:title 在这里不是有效的顶层语句(不像流程图或甘特图),写了会被静默忽略,不会报错也不会显示,别浪费时间加它。

定义服务

architecture-beta
    group sys(cloud)["我的系统"]

    service ui(internet)["前端"] in sys
    service logic(server)["后端"] in sys
    service store(database)["数据库"] in sys
    service ext(server)["支付系统"]

在 MermZen 中试试 →

service id(icon)[标题] in groupId 把服务放进分组里。不写 in groupId 则服务会渲染在所有分组之外——适合表示外部系统(上例中"支付系统"就渲染在"我的系统"外面)。

重要:架构图里的 CJK(中文)标签必须加引号,比如 ["前端"],不能写成 [前端]——这点和流程图不一样,流程图里中文不加引号也没问题,但架构图不加引号会直接解析失败(已实测验证)。

服务之间的连接

architecture-beta
    group sys(cloud)["我的系统"]

    service ui(internet)["前端"] in sys
    service logic(server)["后端"] in sys
    service store(database)["数据库"] in sys
    service ext(server)["支付系统"]

    ui:B -- T:logic
    logic:B -- T:store
    logic:R -- L:ext

在 MermZen 中试试 →

连线必须显式指定两端方向,不是可选项serviceA:方向 -- 方向:serviceB,方向是 T/B/L/R 之一。漏写一端会直接报解析错误,不存在"默认方向"这种兜底。想要箭头就用 --> 而不是 --

完整示例:小型商店系统

architecture-beta
    group sys(cloud)["网店系统"]

    service web(internet)["Web 应用"] in sys
    service api(server)["API 网关"] in sys
    service orders(server)["订单服务"] in sys
    service payments(server)["支付服务"] in sys
    service db(database)["订单数据库"] in sys
    service cache(disk)["会话缓存"] in sys

    web:B -- T:api
    api:B -- T:orders
    orders:B -- T:db
    orders:R -- L:payments
    api:R -- L:cache

在 MermZen 中试试 →

六个服务,每条边都是纯粹的 R-L 或 T-B 直线,没有任何服务被两个不同方向同时连入——这是有意为之的,也是下一节要讲的重点。

真实局限:斜线会穿过标签

这是这个图表类型最大的坑,已经实测确认,不是道听途说:斜向的边(一端用水平方向锚点、另一端用垂直方向锚点,且两个服务没有对齐)可能直接画穿相邻服务的标签,即便锚点语法完全正确。底层的布局引擎(cytoscape.js-fcose,一个力导向求解器)在摆放服务时不会为斜穿的边预留避让空间。

具体会在以下情况出现:

这个问题在语法层面无解。可靠的规避方法只有:

  1. 只用纯 R-L、T-B 直线边,避免斜向弯折。
  2. 避免多向汇入:不要让两个服务从不同方向同时连到第三个服务。
  3. 规模保持小。服务越多,自动布局把东西摆在边路径上的概率就越高。像上面"商店系统"这种大致线性、6-8 个服务的规模是实际的上限。
  4. 不要嵌套分组group 嵌套在另一个 group 里会在父分组的约束之上再加一层约束——已实测确认,这会明显增加"直线"边最终却被渲染成斜线的概率。优先用一个扁平分组,而不是嵌套子分组。

如果遇到这个问题,且确实需要超过 8 个服务或多处汇入汇出,改用带 subgraph 的流程图——牺牲云图标,换来真正的布局控制(direction、分组、节点排序),这些架构图都没有。

其他要知道的事

快速参考

语法 作用
architecture-beta 声明架构图
group id(icon)[标题] 定义分组;图标:clouddatabasediskinternetserver
group id(icon)[标题] in parentId 把分组嵌套进另一个分组(会增加布局出错风险,见上文)
service id(icon)[标题] 在任何分组之外定义服务
service id(icon)[标题] in groupId 在分组内定义服务
a:方向 -- 方向:b 无箭头连线,方向必须指定(T/B/L/R
a:方向 --> 方向:b 带箭头连线
a:方向 -[标签]- 方向:b 带标签的连线

下一步

如果系统组件超过 8 个,或者需要精确的布局控制,请查看流程图教程


要试运行上面的代码,点击打开编辑器并粘贴代码。