PlantUML 画部署图:蓝绿部署、灰度发布与金丝雀发布
部署图(Deployment Diagram)是架构评审、团队对齐、故障排查最重要的图之一。用 PlantUML 的 deployment 视图,可以精确描述服务器、容器、网络拓扑和部署策略。
部署图是什么
部署图描述软件的物理部署结构——在哪台服务器上运行、用什么容器、有没有负载均衡、数据库在哪。它回答”这个系统是怎么跑起来的”这个问题。
对比:
- 组件图:描述软件模块之间的关系(逻辑结构)
- 部署图:描述硬件/容器和网络拓扑(物理结构)
适合场景:架构设计评审、运维交接、故障复盘、技术方案文档。
一、最小部署图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @startuml skinparam componentStyle rectangle
node "Web Server" { component "Frontend" as fe }
node "API Server" { component "Backend" as be }
database "PostgreSQL" as db
fe --> be : HTTPS be --> db : SQL @enduml
|
node 是物理节点(服务器/容器)
component 是软件组件
--> 是连接箭头
database 是数据库特殊节点
二、蓝绿部署(Blue-Green Deployment)
蓝绿部署用两套完全相同的生产环境(蓝 + 绿),切换时把流量整体切到新版本, rollback 只需要切回去。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| @startuml skinparam componentStyle rectangle
title 蓝绿部署
node "负载均衡器" as lb { component "Nginx" }
node "蓝环境 (Blue) v1.0" as blue { component "App-Blue" as app_blue component "Worker-Blue" as w_blue }
node "绿环境 (Green) v1.1" as green { component "App-Green" as app_green component "Worker-Green" as w_green }
database "Redis" as redis database "PostgreSQL" as db
lb -[#green,dashed]-> app_green : 流量指向 Green\n(切换后) lb -[#blue, bold]-> app_blue : 流量指向 Blue\n(当前生产)
app_blue --> redis app_blue --> db app_green --> redis app_green --> db @enduml
|
蓝绿部署要点:
- 两套环境配置完全一致(除了版本)
- 切换在负载均衡器一层完成(改 upstream 配置)
- 切换过程用户无感知(原子切换)
- rollback = 把流量切回旧环境
三、金丝雀发布(Canary Release)
金丝雀发布逐步把流量从旧版本迁移到新版本——先放 5% 流量观察,没问题再扩大比例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| @startuml skinparam componentStyle rectangle
title 金丝雀发布
node "负载均衡器" as lb { component "Nginx" }
node "旧版本 v1.0" as old { component "App v1.0" as app_old note bottom: 95% 流量\n当前生产版本 }
node "新版本 v1.1 (Canary)" as new { component "App v1.1" as app_new note bottom: 5% 流量\n灰度测试版本 }
database "Shared DB" as db
lb --> app_old : 95% lb -[#red,dashed]--> app_new : 5% (Canary)\n放大条件:\n- 错误率 < 0.1%\n- P99 < 200ms
app_old --> db app_new --> db @enduml
|
金丝雀发布要点:
- 流量分割在负载均衡器层配置(Nginx upstream weight)
- 监控指标:错误率、延迟、业务指标
- 放大条件通常写进注释让团队知道升级标准
- 比蓝绿更安全(金丝雀出问题只影响 5% 用户)
四、滚动发布(Rolling Deployment)
滚动发布在同一组机器上逐台升级,用 Kubernetes ReplicaSet 管理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| @startuml skinparam componentStyle rectangle
title 滚动发布
node "Kubernetes Cluster" as k8s { node "Pod-1 (v1.0 → v1.1)" as pod1 { component "App v1.0" } node "Pod-2 (v1.0)" as pod2 { component "App v1.0" } node "Pod-3 (v1.0)" as pod3 { component "App v1.0" } }
node "Service" as svc { component "K8s Service\n(type: LoadBalancer)" }
database "Backend DB" as db
svc --> pod1 svc --> pod2 svc --> pod3 pod1 --> db pod2 --> db pod3 --> db @enduml
|
滚动发布要点:
- 同一时间部分 Pod 是旧版本,部分是新版本
- 优点:不需要双倍资源
- 缺点:版本共存期间有兼容性问题风险
- Kubernetes 默认策略:25% maxUnavailable + 25% maxSurge
五、Kubernetes 部署拓扑
K8s 是现代部署的事实标准,一个完整的前后端 K8s 部署:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| @startuml skinparam componentStyle rectangle skinparam nodesep 50 skinparam ranksep 50
title Kubernetes 部署架构
node "AWS / 云厂商" { node "Region: us-east-1" { node "Namespace: production" { node "Ingress Controller" { component "Nginx Ingress" } node "Frontend" { component "Deployment\nfrontend-v3\nReplicas: 3" as fe component "Service\nClusterIP" as fe_svc } node "API Gateway" { component "Deployment\napi-gateway\nReplicas: 2" as api component "Service\nClusterIP" as api_svc } node "Backend" { component "Deployment\nbackend-v2\nReplicas: 3" as be component "Service\nClusterIP" as be_svc } database "Database Tier" { database "RDS PostgreSQL\nMulti-AZ" as rds database "ElastiCache Redis\nCluster mode" as redis } } } }
Ingress --> fe fe --> api_svc api_svc --> api api --> be_svc api --> rds api --> redis be --> be_svc be --> rds be --> redis @enduml
|
六、部署图画法规范
6.1 节点层次
1
| 云厂商 > Region > VPC/Namespace > 可用区 > 节点 > Pod > Container > 进程
|
部署图通常画到 Pod 层(容器粒度)就够了,不需要画到进程级别。
6.2 连接线语义
1 2 3 4 5 6 7
| @startuml A --> B : 同步调用 A ->> B : 异步消息 A o-- oB : 弱依赖 A *-- B : 组合(生命周期绑定) A ..> B : 依赖(单向) @enduml
|
-->:同步/同步调用,常见
->>:异步消息队列
..>:单向依赖(不持有引用)
*--:组合(父销毁子也销毁)
6.3 节点样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| skinparam node { BackgroundColor #F0F8FF BorderColor #4682B4 FontSize 12 }
skinparam database { BackgroundColor #FFF8DC BorderColor #DAA520 }
skinparam component { BackgroundColor #F5F5F5 BorderColor #696969 }
|
6.4 颜色语义
| 颜色 |
语义 |
| 红色虚线 |
新版本 / Canary |
| 绿色虚线 |
备用环境 |
| 蓝色实线 |
当前生产流量 |
| 橙色 |
告警 / 特殊处理 |
七、和 C4 部署图的对比
| 维度 |
PlantUML Deployment |
C4 部署图 |
| 粒度 |
精确(节点+组件) |
抽象(系统/容器/组件) |
| 标准化 |
UML 规范 |
C4 模型(非 UML) |
| K8s 支持 |
原生 |
需要 PlantUML C4-PlantUML lib |
| 图表可读性 |
复杂图较乱 |
C4 更整洁 |
| 适合读者 |
运维/DevOps |
架构师/产品 |
架构师和 PM 适合看 C4 部署图;运维和 DevOps 适合看 PlantUML 部署图(更精确)。
八、常见报错
| 报错 |
原因 |
修复 |
| 节点不显示 |
node 拼写错误 |
检查 node "name" as alias 语法 |
| 连接线乱飞 |
默认自动 layout |
加 skinparam linetype ortho |
| 组件在节点外 |
component 没写在 node 里 |
把 component 声明放进 node 块 |
| 虚线变实线 |
--> 和 ..> 用混了 |
--> 是实线,..> 是虚线 |
小结
PlantUML 部署图记住 4 点:
node = 物理/容器节点,component = 软件组件,database = 数据库
- 蓝绿部署 = 两套环境 + 负载均衡器整体切换,rollback 成本低
- 金丝雀发布 = 流量分割(5% → 30% → 100%),灰度观察更安全
- 滚动发布 = 同组机器逐台升级,K8s 原生支持,需要考虑版本兼容性
部署图画法规范:节点层次按 云厂商 → Region → Namespace → Pod 划分;连接线语义清晰(同步/异步/依赖);用颜色区分新旧版本。