架构图怎样绘制最方便?

架构图怎样绘制最方便?

本文将给大家介绍一种简洁明了软件架构可视化模型——C4模型,并手把手教大家如何使用代码绘制出精美的C4架构图。

阅读本文之后,读者画的架构图将会是这样的:

C4是软件架构可视化的一种方案。架构可视化,指的是用图例的方式,把软件架构设计准确、清晰、美观地表示出来。架构可视化不是指导开发者如何进行架构设计,而是指导开发者将架构设计表达出来,产出简洁直观的架构图。

架构可视化的方法有很多,主流的有“4+1”视图模型、C4模型。视图模型描述的是架构本身,架构确定之后,不管用什么模型去表达,本质上都应该是一样的,并没有优劣之分。

C4 模型是一种易于学习、对开发人员友好的软件架构图示方法,C4模型没有规定使用特定的图形、特定的建模语言来画图,因而使用者可以非常灵活地产出架构图。

C4模型将系统从上往下分为System Context, Containers, Components, Code四层视图,每一层都是对上一层的完善和展开,层层递进地对系统进行描述,如下图。

System Context(系统上下文)视图位于顶层,是软件系统架构图的起点,表达的是系统的全貌。System Context视图重点展示的是系统边界、系统相关的用户、其他支撑系统以及与本系统的交互。本层不涉及到具体细节(例如技术选型、协议、部署方案和其他低级细节),因此System Context可以很好地向非技术人员介绍系统。

示例:

这是该网上银行系统的系统上下文图。它显示了使用它的人,以及与该系统有关系的其他软件系统。网上银行系统是将要建设的系统,银行的个人客户使用网上银行系统查看其银行账户的信息并进行支付。网上银行系统本身使用银行现有的大型机银行系统来执行此操作,并使用银行现有的电子邮件系统向客户发送电子邮件。

图例:

Container(容器)视图是对System Context的放大,是对System Context细节的补充。

注意这里的容器,指的不是Docker等容器中间件。Container的描述范围是一个可单独运行/可部署的单元。Container一般指的是应用以及依赖的中间件,例如服务器端 Web 应用程序、单页应用程序、桌面应用程序、移动应用程序、数据库架构、文件系统、Redis、ElasticSeach、MQ等。

Container显示了软件架构的高级形状以及系统内各容器之间的职责分工。

在Container这一层,还显示了系统的主要的技术选型以及容器间的通信和交互。

示例:

网上银行系统(此时System Contenxt中的系统已经被展开,所以用虚线框表示)由五个容器组成:服务器端 Web 应用程序、单页应用程序、移动应用程序、服务器端 API 应用程序和数据库。

该容器图的图例如下,主要是引入了数据库、APP、浏览器的图例。

将单个容器放大,则显示了该容器内部的组件。Component(组件)视图显示了一个容器是如何由许多“组件”组成的,每个组件是什么,它们的职责以及技术实现细节。

示例:

图例:

放大组件视图,则得到出组件的Code视图(代码视图)。

Code视图一般采用 UML 类图、ER图等。Code视图是一个可选的详细级别,通常可以通过 IDE 等工具按需生成。除了最重要或最复杂的组件外,不建议将这种详细程度用于其他任何内容。

在注重敏捷开发的今天,一般不建议产出Code视图。

C4 模型提供了单个软件系统的静态视图,不管是 System Context、Container、Component都是针对单个软件系统的进行描述的,但在实际中软件系统不会孤立存在。为描述所有这些软件系统如何在给定的企业、组织、部门等中与其他系统组合在一起,C4采用扩展视图System Landscape (系统景观图)。

系统景观图实际上只是一个没有特定关注的软件系统的系统上下文图(System Context diagram),系统景观图内的软件系统都可以采用C4进行深入分析。

示例:

图例:

Dynamic diagram(动态图)用于展示静态模型中的元素如何在运行时协作。动态图允许图表元素自由排列,并通过带有编号的箭头以指示执行顺序。

示例:

图例:

Deployment diagram(部署图)用于说明静态模型中的软件系统(或容器)的实例在给定环境(例如生产、测试、预发、开发等)中的部署方案。

C4的部署图基于UML 部署图,但为了突出显示容器和部署节点之间的映射会做略微的简化。

部署节点表示表示软件系统/容器实例运行的位置,类似于物理基础架构(例如物理服务器或设备)、虚拟化基础架构(例如 IaaS、PaaS、虚拟机)、容器化基础架构(例如 Docker 容器)、执行环境(例如数据库服务器、Java EE web/应用服务器、Microsoft IIS)等。部署节点可以嵌套,也可以将基础设施节点包括进去,例如 DNS 服务、负载平衡器、防火墙等。

可以在部署图中随意使用 Amazon Web Services、Azure 等提供的图标,只需确保被使用的任何图标都包含在图例中,不产生歧义。

示例:

网上银行系统的开发环境部署图:

图例

网上银行的生产环境部署图:

图例

为了确保C4模型的架构图的可读性,C4模型提供了作图规范,并且提供了CheckList供自查。

2.9.1 C4模型规范

2.9.2 Review Checklist

C4模型图表绘制完成后,可以通过Review Checklist 进行自查,检查是否有不规范之处。Review Checklist被制成网页,可以通过https://c4model.com/review/ 进行访问。

关于C4模型的架构图的绘制,一般有两种方式:

第一种是采用绘图工具,这类工具直接拖拽元素、调整样式,即可产出图片,例如http://draw.io、PPT等工具。绘图工具的优点是非常灵活,可以满足很多细节需求;缺点是通常调整元素的样式会比较繁琐。

第二种是采用基于文本的绘图工具,根据一定的语法去描述图片元素,最后根据文本自动渲染成图片,例如PlantUML。基于文本的绘图工具的优点是绘图快捷,只要根据语法写出描述文件,即可渲染出来,元素的样式已经默认调试好;缺点是样式不一定符合我们的审美,调整不方便。

本文着重讲解第二种,即基于文本的绘图工具。

基于文本的绘图工具有很多,例如:structurizr、PlantUML、mermaid,分别有自己的语法。

由于IntelliJ Idea、VS Code目前在开发者中非常普及,我们选择使用C4-PlantUML,结合VS Code和IntelliJ Idea分别进行C4模型的绘制。

VS Code环境的安装,见3.2。

IntelliJ Idea环境的安装,见3.3

3.2.1 安装VS Code

直接官网下载安装即可,过程略去。

3.2.2 安装PlantUML插件

在VS Code的Extensions窗口中搜索PlantUML,安装PlantUML插件。

3.2.3 配置VS Code代码片段

安装完PlantUML之后,为了提高效率,我们最好安装PlantUML相关的代码片段。

打开VS Code菜单,层级为Code→Preferences→User Snippets,如下图:

在选择Snippets File Or Create Snippets弹窗中,选择New Global Snippets file,如下图:

在接下来的弹窗中,输入Snippets file的文件名,如下图:

使用浏览器打开以下链接,并将浏览器返回的文本内容粘贴到VS Code编辑区

如图:

3.2.4 安装Graphviz

如果图形渲染出现问题,提示安装graphviz库,直接到graphviz官网安装即可。官网链接如下:

Mac系统推荐采用MacPorts安装。

3.3.1 安装Idea

3.3.2 安装PlantUML Integration插件

3.3.3 安装代码模版

通过以下链接,下载IntelliJ live template。

通过菜单路径 File | Manage IDE Settings | Import Settings ,选择下载的 ZIP文件, c4_live_template.zip,导入并重启Idea即可。

C4-PlantUML的详细语法可以到官网github项目主页(https://github.com/plantuml-stdlib/C4-PlantUML )去了解,在此只做简单介绍。

3.4.1 案例

以某招聘APP服务端架构图(Container级)为例子进行讲解,以下是渲染出来的效果图。

以下是完整plantuml代码:

3.4.2 PlantUML文件

PlantUML文件以puml作为文件扩展名。

3.4.3 @startuml和@enduml

整个文档由@startuml和@enduml包裹,是固定语法。

3.4.4 注释

PlantUML中使用单引号(即')作为注释标识。

3.4.5 include语句

首先是C4各个视图的include语句,以下语句代表引入了C4的Context、Container、Component视图。

其次是图标库:

注意这里有一个define语法,先通过 !define 定义一个标识,之后使用该标识的地方都会被替换

使用图标时,只需要在元素的声明语句中加入$sprite="xxx"即可。

3.4.6 C4模型静态元素

Person:系统的用户,可能是人或者其他系统

System:代表即将建设的系统,通常渲染为蓝色方块。System_Ext:代表已存在的系统,通常渲染为灰色方块。System_Boundary:某系统展开为容器时,则将System改为System_Boundary,代表系统的边界,内部放置容器元素,通常渲染为虚线框。

Container:待建设的容器,通常渲染为蓝色方块。Container_Ext:已建设容器,通常渲染为灰色方块。Container_Boundary:某容器展开为组件之后,则将Container改为Container_Boundary,代表容器的边界,内部放置组件元素,通常渲染为虚线框。

ContainerDb:待建设数据库,通常渲染为蓝色圆柱。ContainerQueue:待建设消息队列,通常渲染为水平放置的蓝色圆柱。

Component:待建设组件,通常渲染为蓝色方块。Component_Ext:已建设组件,通常渲染为灰色方块。

静态元素的语法为:

alias:是图内元素的唯一ID,其他地方可以通过alias进行引用,比如在Rel中引用label:代表元素的显示名称technology:代表元素采用的核心技术,包括但不限于开发语言、框架、通信协议等description:代表元素的简单描述

对于System_Boundary和Container_Boundary,则只需要alias和label,大括号内是该元素边界内的子元素。

3.4.7 C4模型的关系元素

Rel代表两个元素之间的关系,其语法为:

from_alias是起点元素的别名,to_alias是终点元素的别名,label则用来说明这个关联关系,technology代表采用的技术、通信协议。例如:

代表iOS客户端通过请求网关接口访问服务端资源,采用HTTPS的通信方式。

建议在绘制Rel时标注出technology。

3.4.8 C4-PlantUML布局

C4-PlantUML提供了多种自动布局方案,我们可以根据实际需要进行选择。

3.4.9 图例

通过SHOW_LEGEND()添加图例。