PlantUml建模工具的一次实践
一直没有一个好的画图工具,一般的画图工具如Visio和亿图,还需要拖拽各种操作不方便,今天实践一下plantUML建模工具,网上有很多资料,只是实践后汇总下。
1. Uml及PlantUml使用场景
UML(Unified Modeling Language)统一建模语言是一个通用的可视化建模语言,用于对软件进行描述、可视化处理、构造和建立软件系统制品的文档。UML 提供了一套描述软件系统模型的概念和图形表示方法,软件开发人员可以使用 UML 对复杂的面向对象软件系统建立可视化的模型。
UML有事物,关系和图三个基本构造块。事物是实体抽象化的最终结果,是模型中的基本成员;关系是将事物联系在一起的方式;图是事物集合的分类。
支持的UML图包括:时序图、状态图、架构图、组件图等等,第3部分会详细举例说明。
2. plantUML安装
主要实践Windows下进行plantUML工具安装。如果不想安装,可以用在线的plantUML工具。另外会找机会介绍docker下plantUML容器版本的安装(离线方式建议docker容器,不用安装依赖包)。
Windows下安装planUML,参考使用sublime+plantUML高效地画图进行安装(sublime text,graphviz,sublime的plantUml插件),此外还有安装JRE并配置环境变量。
FAQ: 安装完sublime的plantUML插件后,sublime工具在Preferences -> Package Settings ->Diagram下的Display Diagrams按钮是灰化的。
解决方法:sublime的plantUML插件中diagram/plantuml. jar下载时文件部分丢失。只要下载后,插件可解压成功到package目录,Display Diagrams按钮可点击非灰化。
3. plantUML绘制常用图
参考plantUML语法学习,本文介绍几种常用场景:时序图、状态图、架构图、组件图和用例图,各个常用图源代码见第4部分。
3.1 时序图
时序图模板3.2. 流程图(活动图)
流程图(活动图)3.3. 组件图
参考openstack及组件简要,绘制组件图如
解决几个问题:node节点如何放置,组件节点如何放置,可以通过 -left->,-right->,-up->,-down-> 进行适当调整node和组件的位置使得组件图更清楚明了。
组件图3.4. 状态图
参考操作系统进程的状态转换,绘制状态图
状态图3.5 架构图
参考openstack及组件简要,绘制架构图如
架构图3.6 原例图
参考天猫购物付账过程,绘制用例图如下(端到端)
用例图4. plantUML常用图的源代码
4.1 时序图的源代码
@startuml
title 时序图通用模板
actor Aparticipant B
box "db_adaptor" #LightBlue
collections db_adaptor1
collections db_adaptor2
end box
database db1
database db2
== 子流程1 ==
A -> B: post req1
note left: 左侧备注
activate B
A <[#0000FF]-B:ack,jobid
... 延迟5秒钟 ...
A --> B: get 查询job进度
note over A,B #green:一直查询job直到成功
B -> db_adaptor1: post req2
db_adaptor1 -[#green]-> db1:db operate
db_adaptor2 -[#green]-> db2:db operate
B <-[#0000FF]- db_adaptor1:ack响应200成功
note right: 右侧备注
A <-[#0000FF]- B: ack响应200,进度100
deactivate B
@enduml
4.2 流程图的源代码
@startuml
title 流程(活动)图通用模板
start
if (是否鉴权) then (yes)
-[#blue]->
if (kestone token是否过期) then (yes)
:鉴权失败;
if (是否申请keystone token成功) then (yes)
:keystone 生成新token;
:nova-api;
else (no)
:返回生成token失败;
stop
endif
else (no)
-[#green]->
:nova-api;
endif
else (no)
-[#green]->
:nova-api;
endif
:nova-sechdule;
while (是否超过调度最大次数) is (no)
fork
:disk filter;
fork again
:mem filter;
fork again
:cpu filter;
fork again
:numa filter;
end fork
if (是否调度成功) then (yes)
:nova-compute;
stop
else (no)
endif
endwhile (yes)
:Not valid host;
stop
@enduml
4.3 组件图的源代码
@startuml
package "package Horizon" {
[Component Horizon] <>
}
cloud {
[cloud adaptor]
}
node "keystone node main service" { keystone_rest -> [Component \n keystone api]
[Component \n keystone api]
}
node "nova node main service" {
nova_rest -> [Component \n nova api]
[Component \n nova api]
[Component \n nova db]
[Component \n nova sechdule]
[Component \n nova compute]
[Component \n nova queue]
[Component \n nova conductor]
}
node "neutron node main service" {
neutron_rest --> [Component \n neutron plugin agent]
[Component \n neutron plugin agent]
}
node "glance node main service" {
glance_rest -> [Component \n glance api]
[Component \n glance api]
}
node "cinder node main service" {
cinder_rest -> [Component \n cinder api]
[Component \n cinder api]
}
node "hypervisor" {
[Component \n hypervisor]
}
[Component Horizon] --> [cloud adaptor]
[cloud adaptor] -> [keystone_rest] :1
[cloud adaptor] -> [nova_rest] :2
[Component \n nova api] <-> [keystone_rest] :3
[Component \n nova api] <-> [Component \n nova db]:4
[Component \n nova api] <-down-> [Component \n nova queue]:5
[Component \n nova queue] -right-> [Component \n nova sechdule]:6
[Component \n nova sechdule] -left-> [Component \n nova db]:7
[Component \n nova sechdule] <- [Component \n nova db]:8
[Component \n nova queue] <- [Component \n nova sechdule]:9
[Component \n nova queue] -down-> [Component \n nova compute]:10
[Component \n nova queue] <- [Component \n nova compute]:11
[Component \n nova queue] -left-> [Component \n nova conductor]:12
[Component \n nova conductor] -left-> [Component \n nova db]:13
[Component \n nova conductor] -up-> [Component \n nova db]:14
[Component \n nova queue] <- [Component \n nova conductor]:15
[Component \n nova queue] -> [Component \n nova compute]:16
[Component \n nova compute] -down-> glance_rest:17
glance_rest <-> keystone_rest:18
[Component \n nova compute] <- glance_rest:19
[Component \n nova compute] -> neutron_rest:20
neutron_rest <-> keystone_rest:21
[Component \n nova compute] <- neutron_rest:22
[Component \n nova compute] -> cinder_rest:23
cinder_rest <-> keystone_rest:24
[Component \n nova compute] <- cinder_rest:25
[Component \n nova compute] -down-> [Component \n hypervisor]:26
@enduml
4.4 状态图的源代码
@startuml
title 操作系统进程状态转换
state create: 进程创建态
create: 如何创建进程,进程资源占用
create: 进程下线程多少个
state ready:进程就绪态
state running:进程运行态
state blocked:进程阻塞态
state terminal:进程终止态
terminal:进程资源释放
state init:资源池
init --> create:资源申请
create --> ready:就绪队列允许接纳新进程,进程移入就绪队列
ready --> running:调度程序将就绪状态的进程分配处理机进入运行态
running --> ready:正在执行的进程因时间片用完而被暂停执行
running --> ready:可抢占调度方式中,因优先级低进入就绪队列
running --> blocked:正在执行的进程因等待某事件A(I/O)而无法执行
running --> blocked:正在执行的进程因等待某事件A(申请缓冲区)而无法执行
running --> blocked:正在执行的进程因等待某事件A(等待信号)而无法执行
blocked --> ready:进程所等待的事件A发生了,进程进入就绪队列
blocked --> terminal:因任务完成完成,变为终止状态
blocked --> terminal:因某种异常事件,变为终止状态
terminal --> init:释放资源
@enduml
4.5 架构图的源代码
@startuml
title openstack架构图
sprite $bProcess jar:archimate/business-process
sprite $aService jar:archimate/application-service
sprite $aComponent jar:archimate/application-component
rectangle "Horizon" as H <<$bProcess>> #yellow
rectangle "Keystone" as K <<$aService>> #green
rectangle "Nova" as Nova <<$aService>> #green
rectangle "Neutron" as Neutron <<$aService>> #green
rectangle Cinder <<$aService>> #green
rectangle Glance <<$aService>> #green
H *-down- K :1
K *-down- Nova :2
K *-down- Neutron
K *-down- Cinder
K *-down- Glance
Neutron <-right- Nova
Nova -right-> Cinder
Nova -right-> Glance
rectangle "neutron\n server" as ns <<$aComponent>> #A9DCDF
rectangle "neutron\n dhcp" as nh <<$aComponent>> #A9DCDF
rectangle "neutron\n l3" as nl3 <<$aComponent>> #A9DCDF
rectangle "neutron\n plugin" as np <<$aComponent>> #A9DCDF
rectangle "nova\n api" as na <<$aComponent>> #A9DCDF
rectangle "nova\n sechdule" as nsech <<$aComponent>> #A9DCDF
rectangle "nova\n compute" as ncom <<$aComponent>> #A9DCDF
rectangle "glance\n api" as ga <<$aComponent>> #A9DCDF
rectangle "glance\n registry" as gr <<$aComponent>> #A9DCDF
rectangle "glance\n image store" as gis <<$aComponent>> #A9DCDF
rectangle "cinder\n api" as ca <<$aComponent>> #A9DCDF
rectangle "cinder\n sechdule" as cs <<$aComponent>> #A9DCDF
rectangle "cinder\n volume" as cv <<$aComponent>> #A9DCDF
rectangle "cinder\n backup" as cb <<$aComponent>> #A9DCDF
np .right.> ns
np .down.> nh
np .down.> nl3
na .right.> nsech
na .down.> ncom
ga .right.> gr
ga .down.> gis
ca .right.> cs
ca .down.> cv
ca .down.> cb
Neutron -down-> np
Nova -down-> na :3
Glance -down-> ga
Cinder -down-> ca
ncom -right-> ga :4
ncom -right-> ca :5
ncom -left-> ns :6
legend leftExample from the "openstack架构图".
<$bProcess> :business process
<$aService> : application service
<$aComponent> : appplication component
__> : 组件间消息
---> : 组件内消息
endlegend
@enduml
4.6 用例图的源代码
@startuml
title 用例图
left to right direction
actor buyer
actor seller
rectangle plaform {
buyer <--> (trade)
(App) -left.> (trade) : use
(help) .> (trade) : extends
(trade) <--> (goods):select
(discount) -left.> (goods) : of
(goods) <--> (payment):pay
(支付宝) -left.> (payment):of
(银行卡) .> (payment):of
(payment) --> seller
(payment) <-- seller
buyer <-- (trade)
}
buyer2 --> (Usecase2)
buyer2 <-- (Usecase2)
@enduml