PlantUML 程序员绘图工具
最强 Markdown 在线编辑工具
类图
@startuml
gender_mode_t << (E,orchid) >>
team_config_t <|-- class_config_t
team_config_t <|-- gender_mode_t
@enduml
流程图
@startuml
start
:进入采集;
repeat
:发送mode;
repeat while (Android端返回模式?) is (no)
if (返回的mode?) then (one)
:touch模式;
repeat
repeat while (是否touch down?) is (no)
repeat
:capture;
repeat while (capture完成?) is (no)
:发送captured到android;
else (two)
:button模式;
:点击button;
:发送click到安卓;
:延时(等待android端点亮采集区域);
repeat
:capture;
repeat while (capture完成?) is (no)
:发送captured到android;
endif
:退出采集;
@enduml
网络图
@startuml asus_openvpn_tun
nwdiag {
internet [shape = cloud];
internet -- router;
network internet_MAN {
router
router_ac86u
router_ac88u
}
network internal_openvpn {
router_ac86u [address = "10.8.0.0"]
router_ac88u [address = "10.8.0.x"]
openvpn_client1 [address = "10.8.0.x"]
}
network internal_ZT {
router_ac86u [address = "192.168.52.1"];
nas [address = "192.168.52.2"];
ubuntu_server [address = "192.168.52.3"];
}
network internal_KS {
router_ac88u [address = "192.168.51.1"];
windows_server [address = "192.168.51.2"];
macos_server [address = "192.168.51.5"];
}
}
@enduml
时序图
基础
@startuml
A -> B: do something
B -> A: do something
@enduml
不同的角色
@startuml
actor Foo1
boundary Foo2
control Foo3
entity Foo4
database Foo5
collections Foo6
Foo1 -> Foo2 : To boundary
Foo1 -> Foo3 : To control
Foo1 -> Foo4 : To entity
Foo1 -> Foo5 : To database
Foo1 -> Foo6 : To collections
@enduml
不同的箭头样式
@startuml
Bob ->x Alice
Bob -> Alice
Bob ->> Alice
Bob -\ Alice
Bob \\- Alice
Bob //-- Alice
Bob ->o Alice
Bob o\\-- Alice
Bob <-> Alice
Bob <->o Alice
Bob -[#red]> Alice : hello
Alice -[#0000FF]->Bob : ok
@enduml
分页
@startuml
Alice -> Bob : message 1
Alice -> Bob : message 2
newpage
Alice -> Bob : message 3
Alice -> Bob : message 4
newpage A title for the\nlast page
Alice -> Bob : message 5
Alice -> Bob : message 6
@enduml
分段
@startuml
== Initialization ==
Alice -> Bob: Authentication Request
Bob --> Alice: Authentication Response
== Repetition ==
Alice -> Bob: Another authentication Request
Alice <-- Bob: another authentication Response
@enduml
生命线
@startuml
participant User
User -> A: DoWork
activate A #FFBBBB
A -> A: Internal call
activate A #DarkSalmon
A -> B: << createRequest >>
activate B
B --> A: RequestCreated
deactivate B
deactivate A
A -> User: Done
deactivate A
@enduml
图例注脚
@startuml
header Page Header
footer Page %page% of %lastpage%
title Example Title
Alice -> Bob : message 1
note left: this is a first note
Alice -> Bob : message 2
@enduml
综合示例
@startuml
title 借钱与还钱的故事
hide footbox
autonumber
== 借钱阶段 ==
张三 -> 李四 : 我要借钱
box "三方担保" #LightBlue
participant 王五 <<(保,#00FF00)>>
create 王五
张三 -> 王五 : 我来虚拟个担保人
activate 王五
王五 --> 李四 : 我给他担保
destroy 王五
end box
李四 --> 张三 : 借给你
... 一天后 ...
== 还钱阶段 ==
autonumber 12 "<b>(<i>###</i>)"
张三 -> 李四 : 我要还钱
||50||
note left
有借有还,
再借不难!
end note
李四 --> 张三 : 收到欠款
note right: 有诚信!
legend center
这是一个借钱与还钱发生的故事。
故事发生在一个夜黑风高的晚上……
endlegend
@enduml
用例图
买单用例
@startuml
left to right direction
actor 消费者
actor 销售员
rectangle 买单 {
消费者 -- (买单)
(买单) .> (付款) : include
(帮助) .> (买单) : extends
(买单) -- 销售员
}
@enduml
内部系统用例
@startuml
left to right direction
actor : 其它LX提供给TA的后端系统: as otherLxTaBackendService
note top of otherLxTaBackendService
比如tianansp负责活动和文章的服务
比如tiananseason负责西游活动的服务
通过dubbo的rpc方法调用
end note
usecase 修改用户积分 as changeUserPoint
usecase 查询用户总积分 as getUserTotalPoint
usecase 登录校验 as getRestContextByAccessToken
otherLxTaBackendService --> getRestContextByAccessToken:获取用户的登录态[RPC]
otherLxTaBackendService --> changeUserPoint:活动增加或者扣减积分[RPC]
otherLxTaBackendService --> getUserTotalPoint: 查询用户当前总积分[RPC]
@enduml
外部系统用例
@startuml
'left to right default
actor : ta用户: as taUser
usecase 用户登录 as userLogin
usecase 查询积分明细 as findUserPointDetail
usecase 改变积分 as changeUserPointDetail
note bottom of userLogin
TA用户登录
LX交互的后端系统
LX的saas系统
构造登录态
end note
taUser -right-> userLogin: 登录进LX交付的功能[REST]
taUser --> changeUserPointDetail : 修改积分\n阅读文章\n分享文章\n参加活动[REST]
taUser --> findUserPointDetail : 查询积分\n消费获取\n明细[REST]
@enduml
组件图
@startuml
package "组件1" {
["组件1.1"] - ["组件1.2"]
["组件1.2"] -> ["组件2.1"]
}
node "组件2" {
["组件2.1"] - ["组件2.2"]
["组件2.2"] --> [负载均衡服务器]
}
cloud {
[负载均衡服务器] -> [逻辑服务器1]
[负载均衡服务器] -> [逻辑服务器2]
[负载均衡服务器] -> [逻辑服务器3]
}
database "MySql" {
folder "This is my folder" {
[Folder 3]
}
frame "Foo" {
[Frame 4]
}
}
[逻辑服务器1] --> [Folder 3]
[逻辑服务器2] --> [Frame 4]
[逻辑服务器3] --> [Frame 4]
@enduml
状态图
@startuml
scale 640 width
[*] --> NotShooting
state NotShooting {
[*] --> Idle
Idle --> Processing: SignalEvent
Processing --> Idle: Finish
Idle --> Configuring : EvConfig
Configuring --> Idle : EvConfig
}
state Configuring {
[*] --> NewValueSelection
NewValueSelection --> NewValuePreview : EvNewValue
NewValuePreview --> NewValueSelection : EvNewValueRejected
NewValuePreview --> NewValueSelection : EvNewValueSaved
state NewValuePreview {
State1 -> State2
}
}
@enduml
积分状态图
@startuml
scale 350 width
left to right direction
hide empty description
state noPointRecord : 没有积分记录
state pointZero : 积分为0
state pointOk : 有积分
[*] --> noPointRecord: 增加积分
noPointRecord --> pointZero: 初始化
pointZero --> pointOk: 增加/消耗积分
pointOk --> [*]
@enduml
活动图
@startuml
header 登录接口活动图
footer 登录接口活动图
|tomcat|
start
:参数校验]
if (参数校验通过 ?) then (yes)
elseif (字符串为空) then (no)
stop
else (其它校验错误)
stop
endif
|TA服务端|
:用户code远程校验;
|LX Saas|
:saas注册登录;
|mysql|
:登记到saasUser;
|redis|
:保存令牌到Redis;
|tomcat|
:组装响应参数;
stop
@enduml
部署图
@startuml
header TA项目物理架构图
footer TA项目物理架构图
left to right direction
actor TaUser as taUser
node TaApp as taApp {
agent LxSDK as lxsdk
agent TaClient as taClient
}
folder tiananuser_folder {
cloud tiananuserCluster
node tomcat1_tiananuser
node tomcat2_tiananuser
node tomcat3_tiananuser
tiananuserCluster -down-> tomcat1_tiananuser
tiananuserCluster -down-> tomcat2_tiananuser
tiananuserCluster -down-> tomcat3_tiananuser
}
folder tianansp_folder {
cloud tiananspCluster
node tomcat1_tianansp
node tomcat2_tianansp
node tomcat3_tianansp
tiananspCluster -down-> tomcat1_tianansp
tiananspCluster -down-> tomcat2_tianansp
tiananspCluster -down-> tomcat3_tianansp
}
node Nginx as nginx
nginx --> tiananuserCluster:负载均衡/路由
nginx --> tiananspCluster:负载均衡/路由
taUser --> taApp : 访问
taApp --> nginx:http/https
database tiananuser_database[
用户登录数据库
]
database tianansp_database[
运营活动数据库
]
database redis[
redis缓存
]
tiananuser_folder -down-> tiananuser_database
tianansp_folder -right-> tianansp_database
tiananuser_folder -down-> redis
tianansp_folder -up-> redis
node zk [
zookeeper注册中心
dubbo的消费者跟生产者通信中间件
定时任务elasticjob的配置中间件
]
tiananuser_folder -down-> zk
tianansp_folder -up-> zk
node apollo [
apollo配置中心
]
queue kafka[
kafka集群
]
tiananuser_folder -down-> apollo
tianansp_folder -up-> apollo
tiananuser_folder -down-> kafka
tianansp_folder -up-> kafka
file fileCDN [
七牛云或者阿里云存储
]
tiananuser_folder -down-> fileCDN
tianansp_folder -up-> fileCDN
cloud ELK {
node elsticSearch
node filebeat
node kibana
}
node kubernetes{
node healmcharts[
交付服务
]
node harbor[
harbor监控管理kubernetes对象
]
}
tiananuser_folder -down-> ELK:日志写入
tianansp_folder -up-> ELK:日志写入
tiananuser_folder -down-> kubernetes:发布和管控docker节点
tianansp_folder -up-> kubernetes:发布和管控docker节点
@enduml
C4 - PlantUML
C4 - 架构图
@startuml C4_Elements
!includeurl https://raw.githubusercontent.com/RicardoNiepel/C4-PlantUML/master/C4_Context.puml
!includeurl https://raw.githubusercontent.com/RicardoNiepel/C4-PlantUML/master/C4_Container.puml
!includeurl https://raw.githubusercontent.com/RicardoNiepel/C4-PlantUML/master/C4_Component.puml
System(systemAlias, "System", "这可以看作系统上下文(Context)")
Container(containerAlias, "Container", "这是Container")
Person(personAlias, "Person", "这可以看作是组件(Component)")
Rel(personAlias, containerAlias, "Label", "设置关联关系")
@enduml
C4 - 容器图
@startuml Basic Sample
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
Person(admin, "Administrator")
System_Boundary(c1, "Sample System") {
Container(web_app, "Web Application", "C#, ASP.NET Core 2.1 MVC", "Allows users to compare multiple Twitter timelines")
}
System(twitter, "Twitter")
Rel(admin, web_app, "Uses", "HTTPS")
Rel(web_app, twitter, "Gets tweets from", "HTTPS")
@enduml
C4 - 实例图
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
!define DEVICONS https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons
!define FONTAWESOME https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/font-awesome-5
!include DEVICONS/angular.puml
!include DEVICONS/java.puml
!include DEVICONS/msql_server.puml
!include FONTAWESOME/users.puml
LAYOUT_WITH_LEGEND()
Person(user, "Customer", "People that need products", $sprite="users")
Container(spa, "SPA", "angular", "The main interface that the customer interacts with", $sprite="angular")
Container(api, "API", "java", "Handles all business logic", $sprite="java")
ContainerDb(db, "Database", "Microsoft SQL", "Holds product, order and invoice information", $sprite="msql_server")
Rel(user, spa, "Uses", "https")
Rel(spa, api, "Uses", "https")
Rel_R(api, db, "Reads/Writes")
@enduml
C4 - 关系图
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
HIDE_STEREOTYPE()
Person(a, "A")
Person(b, "B")
Person(c, "C")
Person(d, "D")
Person(e, "E")
Lay_U(a, b)
Lay_R(a, c)
Lay_D(a, d)
Lay_L(a, e)
Person(x, "X")
System(s1, "S1")
System(s2, "S2")
System(s3, "S3")
System(s4, "S4")
Rel_U(x, s1, "uses")
Rel_R(x, s2, "uses")
Rel_D(x, s3, "uses")
Rel_L(x, s4, "uses")
@enduml
C4 - 复杂的容器图
@startuml "techtribesjs"
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
' uncomment the following line and comment the first to use locally
' !include C4_Container.puml
LAYOUT_TOP_DOWN()
'LAYOUT_AS_SKETCH()
LAYOUT_WITH_LEGEND()
Person_Ext(anonymous_user, "Anonymous User")
Person(aggregated_user, "Aggregated User")
Person(administration_user, "Administration User")
System_Boundary(c1, "techtribes.js"){
Container(web_app, "Web Application", "Java, Spring MVC, Tomcat 7.x", "Allows users to view people, tribes, content, events, jobs, etc. from the local tech, digital and IT sector")
ContainerDb(rel_db, "Relational Database", "MySQL 5.5.x", "Stores people, tribes, tribe membership, talks, events, jobs, badges, GitHub repos, etc.")
Container(filesystem, "File System", "FAT32", "Stores search indexes")
ContainerDb(nosql, "NoSQL Data Store", "MongoDB 2.2.x", "Stores from RSS/Atom feeds (blog posts) and tweets")
Container(updater, "Updater", "Java 7 Console App", "Updates profiles, tweets, GitHub repos and content on a scheduled basis")
}
System_Ext(twitter, "Twitter")
System_Ext(github, "GitHub")
System_Ext(blogs, "Blogs")
Rel(anonymous_user, web_app, "Uses", "HTTPS")
Rel(aggregated_user, web_app, "Uses", "HTTPS")
Rel(administration_user, web_app, "Uses", "HTTPS")
Rel(web_app, rel_db, "Reads from and writes to", "SQL/JDBC, port 3306")
Rel(web_app, filesystem, "Reads from")
Rel(web_app, nosql, "Reads from", "MongoDB wire protocol, port 27017")
Rel_U(updater, rel_db, "Reads from and writes data to", "SQL/JDBC, port 3306")
Rel_U(updater, filesystem, "Writes to")
Rel_U(updater, nosql, "Reads from and writes to", "MongoDB wire protocol, port 27017")
Rel(updater, twitter, "Gets profile information and tweets from", "HTTPS")
Rel(updater, github, "Gets information about public code repositories from", "HTTPS")
Rel(updater, blogs, "Gets content using RSS and Atom feeds from", "HTTP")
Lay_R(rel_db, filesystem)
@enduml
C4 - 消息总线和微服务
@startuml "messagebus"
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
' uncomment the following line and comment the first to use locally
' !include C4_Container.puml
skinparam wrapWidth 200
skinparam maxMessageSize 200
LAYOUT_TOP_DOWN()
'LAYOUT_AS_SKETCH()
LAYOUT_WITH_LEGEND()
Person(customer, Customer, "A customer")
System_Boundary(c1, "Customer Information") {
Container(app, "Customer Application", "Javascript, Angular", "Allows customers to manage their profile")
Container(customer_service, "Customer Service", "Java, Spring Boot", "The point of access for customer information")
Container(message_bus, "Message Bus", "RabbitMQ", "Transport for business events")
Container(reporting_service, "Reporting Service", "Ruby", "Creates normalised data for reporting purposes")
Container(audit_service, "Audit Service", "C#/.NET", "Provides organisation-wide auditing facilities")
ContainerDb(customer_db, "Customer Database", "Oracle 12c", "Stores customer information")
ContainerDb(reporting_db, "Reporting Database", "MySQL", "Stores a normalized version of all business data for ad hoc reporting purposes")
Container(audit_store, "Audit Store", "Event Store", "Stores information about events that have happened")
}
Rel(customer, app, "Uses", "HTTPS")
Rel_R(app, customer_service, "Updates customer information using", "async, JSON/HTTPS")
Rel_L(customer_service, app, "Sends events to", "WebSocket")
Rel_R(customer_service, message_bus, "Sends customer update events to")
Rel(customer_service, customer_db, "Stores data in", "JDBC")
Rel(message_bus, reporting_service, "Sends customer update events to")
Rel(message_bus, audit_service, "Sends customer update events to")
Rel(reporting_service, reporting_db, "Stores data in")
Rel(audit_service, audit_store, "Stores events in")
Lay_R(reporting_service, audit_service)
@enduml