一、前言

昨天发现了一款非常不错的云系统架构原型图制作库 Diagrams[1],通过它,我们便可以使用代码的方式绘制诸如阿里云、AWS、Azure、K8S 等系统架构原型图。

相比于在 UI 上对各种图标进行拖拽和调整,这种方式更符合我们程序员的使用习惯。

本文不仅要介绍下这个库,也想说说我是如何参与到这个库中以支持阿里云资源。

二、安装

Diagrams 使用 Graphviz[2] 来渲染图表,在安装 diagrams 之前需要先安装 Graphviz[3]。

macOS 用户(如果使用 Homebrew)可以使用 brew install graphviz 的方式来安装 Graphviz。

安装 diagrams 的方式有多种,通过 pip、pipenv 和 poetry 均可:

# 使用 pip (pip3)$ pip install diagrams# 使用 pipenv$ pipenv install diagrams# 使用 poetry$ poetry add diagrams

三、快速开始

# diagram.pyfrom diagrams import Diagramfrom diagrams.alibabacloud.network import SLBfrom diagrams.alibabacloud.compute import ECSfrom diagrams.alibabacloud.database import RDSwith Diagram("Web Service", show=False):    SLB("lb") >> ECS("web") >> RDS("userdb")

执行后,就能生成如下架构图:

$ python diagram.py




系统架构模版 系统架构图制作_系统架构图怎么画


四、指南

Diagrams 库非常容易掌握,我们仅需要掌握三个概念就能轻松绘制云系统架构图:

  • Diagram:这是表示图的最主要的对象,代表一个架构图
  • Node:表示一个节点或系统组件,比如快速开始中的SLB、ECS和RDS都是架构图中的节点
  • Cluster:表示集群或分组,可将多个节点放到一个集群中

4.1 图 Diagram

使用 Diagram 类来创建图环境上下文,使用 with 语法来使用这个上下文。Diagram 的第一个参数是会被用作架构图的名称以及输出的图片文件名(转换为小写+下划线)。

from diagrams import Diagramfrom diagrams.aws.compute import EC2with Diagram("Simple Diagram"):    EC2("web")

运行上述代码,会生成一个包含 EC2 节点的架构图,并存放在当前的 simple_diagram.png 中。

Diagram 类还支持如下参数:

  • outformat:指定输出图片的类型,默认是 png,可以是 png、jpg、svg 和 pdf
  • show:指定是否显示图片,默认是 False
  • graph_attr、node_attr 和 edge_attr:指定 Graphviz 属性选项,用来控制图、点、线的样式,详情查看 参考链接[4]

4.2 节点 Node

目前,Diagrams 支持五类云资源节点,分别是 AWS、Azure、AlibabaCloud、GCP 和 K8S。

节点之间的关系使用操作符来表示,分别是:

  • >>:左节点指向右节点
  • <
  • -:节点互相连接,没有方向

以下是一个例子:

from diagrams import Diagramfrom diagrams.aws.compute import EC2from diagrams.aws.database import RDSfrom diagrams.aws.network import ELBfrom diagrams.aws.storage import S3with Diagram("Web Services", show=False):    ELB("lb") >> EC2("web") >> RDS("userdb") >> S3("store")    ELB("lb") >> EC2("web") >> RDS("userdb") << EC2("stat")    (ELB("lb") >> EC2("web")) - EC2("web") >> RDS("userdb")


系统架构模版 系统架构图制作_系统架构模版_02


Diagrams 不仅支持单个节点的关系建立,还支持一组节点和其他节点的关系建立,使用 list 来表示一组节点。示例如下:

from diagrams import Diagramfrom diagrams.aws.compute import EC2from diagrams.aws.database import RDSfrom diagrams.aws.network import ELBwith Diagram("Grouped Workers", show=False, direction="TB"):    ELB("lb") >> [EC2("worker1"),                  EC2("worker2"),                  EC2("worker3"),                  EC2("worker4"),                  EC2("worker5")] >> RDS("events")


系统架构模版 系统架构图制作_系统架构图怎么画_03


4.3 集群/组 Cluster

当我们需要在架构图上表示几个节点属于一个集群时,就要用到 Cluster。和 Diagram 的使用方式类似,它也是一个上下文管理器,使用 with 语法。 示例如下:

from diagrams import Cluster, Diagramfrom diagrams.aws.compute import ECSfrom diagrams.aws.database import RDSfrom diagrams.aws.network import Route53with Diagram("Simple Web Service with DB Cluster", show=False):    dns = Route53("dns")    web = ECS("service")    with Cluster("DB Cluster"):        db_master = RDS("master")        db_master - [RDS("slave1"),                     RDS("slave2")]    dns >> web >> db_master


系统架构模版 系统架构图制作_RDS_04


Diagrams 还支持嵌套集群,只需嵌套使用 with Cluster() 即可:

from diagrams import Cluster, Diagramfrom diagrams.aws.compute import ECS, EKS, Lambdafrom diagrams.aws.database import Redshiftfrom diagrams.aws.integration import SQSfrom diagrams.aws.storage import S3with Diagram("Event Processing", show=False):    source = EKS("k8s source")    with Cluster("Event Flows"):        with Cluster("Event Workers"):            workers = [ECS("worker1"),                       ECS("worker2"),                       ECS("worker3")]        queue = SQS("event queue")        with Cluster("Processing"):            handlers = [Lambda("proc1"),                        Lambda("proc2"),                        Lambda("proc3")]    store = S3("events store")    dw = Redshift("analytics")    source >> workers >> queue >> handlers    handlers >> store    handlers >> dw


系统架构模版 系统架构图制作_.net_05


五、我是如何贡献代码

看到 Diagrams 库时,我感到很兴奋。我们画示意图无外乎两种,一种是通过UI来画,一种是通过DSL来制作。在流程图、时序图方面,PlantUML[5] 是我很喜欢的 DSL,然而在云系统架构图方面,过去确实没发现相关的库,直到看到了 Diagrams。

在我看到 Diagrams 时,它还只是支持 AWS、Azure、GCP 和 K8S,我心想怎么能没有阿里云呢?这么好的库我岂不是用不了了。既然如此,不如自己动手,丰衣足食吧。阅读 Diagrams 的代码,会发现写的还真不错,代码清晰简单,还提供了完善的脚手架。

对于它所支持的云供应商(比如 AWS),当我们想更新里面的资源时,只需要在 resources/aws 文件夹中更新资源图片,然后执行 ./autogen.sh 即可。./autogen.sh 会对 resources/ 做这么几件事:

  • 将特定云供应商的 svg 图片转换为 png
  • 将特定云供应商的图片调整为圆角图片
  • 自动生成节点类代码
  • 自动生成文档
  • 使用 black 格式化自动生成的代码

对于它所不支持的云供应商(比如 AlibabaCloud),则要先修改脚手架和配置文件以支持新的云供应商,然后遵循上面的方法即可。具体改动内容可见 此 PR[6]。

参与一个开源项目其实就是这么简单,当你发现满足不了你的需求时,就阅读它的源码以了解实现原理,然后再自己动手实现需求,最后就是向作者提个 PR。