name: c4-architecture description: 使用C4模型Mermaid图生成架构文档。当被要求创建架构图、记录系统架构、可视化软件结构、创建C4图或生成上下文/容器/组件/部署图时使用。触发词包括“架构图”、“C4图”、“系统上下文”、“容器图”、“组件图”、“部署图”、“文档架构”、“可视化架构”。
C4 架构文档
使用C4模型图在Mermaid语法中生成软件架构文档。
工作流程
- 理解范围 - 根据受众确定需要哪些C4级别
- 分析代码库 - 探索系统以识别组件、容器和关系
- 生成图表 - 在适当的抽象级别创建Mermaid C4图
- 文档 - 将图表写入Markdown文件,并附带解释性上下文
C4 图级别
根据文档需求选择适当的级别:
| 级别 | 图类型 | 受众 | 显示 | 何时创建 |
|---|---|---|---|---|
| 1 | C4Context | 所有人 | 系统 + 外部参与者 | 总是(必需) |
| 2 | C4Container | 技术 | 应用程序、数据库、服务 | 总是(必需) |
| 3 | C4Component | 开发者 | 内部组件 | 仅当增加价值时 |
| 4 | C4Deployment | DevOps | 基础设施节点 | 用于生产系统 |
| - | C4Dynamic | 技术 | 请求流(编号) | 用于复杂工作流 |
关键见解: “上下文 + 容器图对大多数软件开发团队足够。” 仅当真正增加价值时才创建组件/代码图。
快速开始示例
系统上下文(级别 1)
C4Context
title System Context - Workout Tracker
Person(user, "User", "Tracks workouts and exercises")
System(app, "Workout Tracker", "Vue PWA for tracking strength and CrossFit workouts")
System_Ext(browser, "Web Browser", "Stores data in IndexedDB")
Rel(user, app, "Uses")
Rel(app, browser, "Persists data to", "IndexedDB")
容器图(级别 2)
C4Container
title Container Diagram - Workout Tracker
Person(user, "User", "Tracks workouts")
Container_Boundary(app, "Workout Tracker PWA") {
Container(spa, "SPA", "Vue 3, TypeScript", "Single-page application")
Container(pinia, "State Management", "Pinia", "Manages application state")
ContainerDb(indexeddb, "IndexedDB", "Dexie", "Local workout storage")
}
Rel(user, spa, "Uses")
Rel(spa, pinia, "Reads/writes state")
Rel(pinia, indexeddb, "Persists", "Dexie ORM")
组件图(级别 3)
C4Component
title Component Diagram - Workout Feature
Container(views, "Views", "Vue Router pages")
Container_Boundary(workout, "Workout Feature") {
Component(useWorkout, "useWorkout", "Composable", "Workout execution state")
Component(useTimer, "useTimer", "Composable", "Timer state machine")
Component(workoutRepo, "WorkoutRepository", "Dexie", "Workout persistence")
}
Rel(views, useWorkout, "Uses")
Rel(useWorkout, useTimer, "Controls")
Rel(useWorkout, workoutRepo, "Saves to")
动态图(请求流)
C4Dynamic
title Dynamic Diagram - User Sign In Flow
ContainerDb(db, "Database", "PostgreSQL", "User credentials")
Container(spa, "Single-Page App", "React", "Banking UI")
Container_Boundary(api, "API Application") {
Component(signIn, "Sign In Controller", "Express", "Auth endpoint")
Component(security, "Security Service", "JWT", "Validates credentials")
}
Rel(spa, signIn, "1. Submit credentials", "JSON/HTTPS")
Rel(signIn, security, "2. Validate")
Rel(security, db, "3. Query user", "SQL")
UpdateRelStyle(spa, signIn, $textColor="blue", $offsetY="-30")
部署图
C4Deployment
title Deployment Diagram - Production
Deployment_Node(browser, "Customer Browser", "Chrome/Firefox") {
Container(spa, "SPA", "React", "Web application")
}
Deployment_Node(aws, "AWS Cloud", "us-east-1") {
Deployment_Node(ecs, "ECS Cluster", "Fargate") {
Container(api, "API Service", "Node.js", "REST API")
}
Deployment_Node(rds, "RDS", "db.r5.large") {
ContainerDb(db, "Database", "PostgreSQL", "Application data")
}
}
Rel(spa, api, "API calls", "HTTPS")
Rel(api, db, "Reads/writes", "JDBC")
元素语法
人物和系统
Person(alias, "Label", "Description")
Person_Ext(alias, "Label", "Description") # 外部人物
System(alias, "Label", "Description")
System_Ext(alias, "Label", "Description") # 外部系统
SystemDb(alias, "Label", "Description") # 数据库系统
SystemQueue(alias, "Label", "Description") # 队列系统
容器
Container(alias, "Label", "Technology", "Description")
Container_Ext(alias, "Label", "Technology", "Description")
ContainerDb(alias, "Label", "Technology", "Description")
ContainerQueue(alias, "Label", "Technology", "Description")
组件
Component(alias, "Label", "Technology", "Description")
Component_Ext(alias, "Label", "Technology", "Description")
ComponentDb(alias, "Label", "Technology", "Description")
边界
Enterprise_Boundary(alias, "Label") { ... }
System_Boundary(alias, "Label") { ... }
Container_Boundary(alias, "Label") { ... }
Boundary(alias, "Label", "type") { ... }
关系
Rel(from, to, "Label")
Rel(from, to, "Label", "Technology")
BiRel(from, to, "Label") # 双向
Rel_U(from, to, "Label") # 向上
Rel_D(from, to, "Label") # 向下
Rel_L(from, to, "Label") # 向左
Rel_R(from, to, "Label") # 向右
部署节点
Deployment_Node(alias, "Label", "Type", "Description") { ... }
Node(alias, "Label", "Type", "Description") { ... } # 简写
样式和布局
布局配置
UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1")
$c4ShapeInRow- 每行形状数量(默认:4)$c4BoundaryInRow- 每行边界数量(默认:2)
元素样式
UpdateElementStyle(alias, $fontColor="red", $bgColor="grey", $borderColor="red")
关系样式
UpdateRelStyle(from, to, $textColor="blue", $lineColor="blue", $offsetX="5", $offsetY="-10")
使用 $offsetX 和 $offsetY 修复重叠的关系标签。
最佳实践
基本规则
- 每个元素必须有:名称、类型、技术(如适用)和描述
- 仅使用单向箭头 - 双向箭头会造成歧义
- 用动作动词标记箭头 - “发送电子邮件使用”、“读取自”,不仅仅是“使用”
- 包含技术标签 - “JSON/HTTPS”、“JDBC”、“gRPC”
- 每张图保持少于20个元素 - 将复杂系统拆分为多张图
清晰指南
- 从级别1开始 - 上下文图有助于界定系统范围
- 每文件一张图 - 保持图专注于单个抽象级别
- 有意义的别名 - 使用描述性别名(例如,
orderService而不是s1) - 简洁描述 - 描述尽可能保持50个字符以内
- 始终包含标题 - “[系统名称]的系统上下文图”
避免事项
参见 references/common-mistakes.md 获取详细反模式:
- 混淆容器(可部署)与组件(不可部署)
- 将共享库建模为容器
- 将消息代理显示为单个容器而不是单个主题
- 添加未定义的抽象级别如“子组件”
- 移除类型标签以“简化”图
微服务指南
单一团队所有权
将每个微服务建模为容器(或容器组):
C4Container
title Microservices - Single Team
System_Boundary(platform, "E-commerce Platform") {
Container(orderApi, "Order Service", "Spring Boot", "Order processing")
ContainerDb(orderDb, "Order DB", "PostgreSQL", "Order data")
Container(inventoryApi, "Inventory Service", "Node.js", "Stock management")
ContainerDb(inventoryDb, "Inventory DB", "MongoDB", "Stock data")
}
多团队所有权
当由不同团队拥有时,将微服务提升为软件系统:
C4Context
title Microservices - Multi-Team
Person(customer, "Customer", "Places orders")
System(orderSystem, "Order System", "Team Alpha")
System(inventorySystem, "Inventory System", "Team Beta")
System(paymentSystem, "Payment System", "Team Gamma")
Rel(customer, orderSystem, "Places orders")
Rel(orderSystem, inventorySystem, "Checks stock")
Rel(orderSystem, paymentSystem, "Processes payment")
事件驱动架构
将单个主题/队列显示为容器,而不是单个“Kafka”框:
C4Container
title Event-Driven Architecture
Container(orderService, "Order Service", "Java", "Creates orders")
Container(stockService, "Stock Service", "Java", "Manages inventory")
ContainerQueue(orderTopic, "order.created", "Kafka", "Order events")
ContainerQueue(stockTopic, "stock.reserved", "Kafka", "Stock events")
Rel(orderService, orderTopic, "Publishes to")
Rel(stockService, orderTopic, "Subscribes to")
Rel(stockService, stockTopic, "Publishes to")
Rel(orderService, stockTopic, "Subscribes to")
输出位置
将架构文档写入 docs/architecture/,命名约定:
c4-context.md- 系统上下文图c4-containers.md- 容器图c4-components-{feature}.md- 每个功能的组件图c4-deployment.md- 部署图c4-dynamic-{flow}.md- 特定流的动态图
受众适宜细节
| 受众 | 推荐图 |
|---|---|
| 高管 | 仅系统上下文 |
| 产品经理 | 上下文 + 容器 |
| 架构师 | 上下文 + 容器 + 关键组件 |
| 开发者 | 所有级别按需 |
| DevOps | 容器 + 部署 |
参考
- references/c4-syntax.md - 完整Mermaid C4语法
- references/common-mistakes.md - 避免反模式
- references/advanced-patterns.md - 微服务、事件驱动、部署