1.2 万 Star!超实用的架构图绘制工具

【导语】:你还在用 visio 绘制架构图吗?这有一款绘制系统架构的开源工具,确定不来看看?

简介

Diagrams 可以让你用python代码绘制云系统架构。无需使用任何其他工具(比如 visio),你就可以用它来为一个全新的系统架构进行原型设计。当然它也可以用来绘制你现有的系统架构。Diagrams 目前支持的主要提供商包括:AWS、Azure、GCP、Kubernetes、阿里云、Oracle云等。同时它也支持本地节点、SaaS和主流的编程框架和语言。

Diagram as Code还能让你跟踪各种版本控制系统中的体系结构图变化。

它不能控制任何实际的云资源也不能生成云信息或地形代码。它只能帮你绘制云系统架构图。

这个开源项目的地址是: https:// github.com/mingrammer/d iagrams

安装使用

需要 Python 3.6 版本及以上,使用前请先检测你的 python 版本。

绘制时需要使用 Graphviz,所以你需要先安装 Graphviz。

macOS 用户可以使用 brew install graphviz 命令来下载 Graphviz。

安装 diagrams

# using pip (pip3)
$ pip install diagrams

# using pipenv
$ pipenv install diagrams

# using poetry
$ poetry add diagrams

快速上手

# diagram.py
from diagrams import Diagram
from diagrams.aws.compute import EC2
from diagrams.aws.database import RDS
from diagrams.aws.network import ELB

with Diagram("Web Service", show=False):
    ELB("lb") >> EC2("web") >> RDS("userdb")

运行此代码,将会生成一个如下的图:

在你的工作目录会生成一个web_service.png。

详细介绍

接下来我们主要分四块介绍一下 diagrams 的构成,分别是:图、节点、集群和边。

一、图

Diagram是展现关系图最关键的部分。

基础使用

你可以使用 Diagram 类来创建一个关系图的上下文。Diagram 构造函数的第一个参数是你输出的文件名。我们来看一个例子:

from diagrams import Diagram
from diagrams.aws.compute import EC2

with Diagram("Simple Diagram"):
 EC2("web")

在 cmd 输入 python diagram.py 来执行下,代码会在你的代码目录生成一个 simple_diagram.png 文件,可以看到里面只有一个 EC2 节点。

Jupyter Notebooks

Diagrams也可以直接在Jupyter的notebook里使用,示例如下:

from diagrams import Diagram
from diagrams.aws.compute import EC2

with Diagram("Simple Diagram") as diag:
    EC2("web")
diag

可选项

你可以指定输出文件的格式,默认格式是.png,比如将默认的png格式改为jpg格式:

(png, jpg, svg, and pdf) 都是允许的格式

from diagrams import Diagram
from diagrams.aws.compute import EC2

with Diagram("Simple Diagram", outformat="jpg"):
 EC2("web")

你也可以使用 filename 参数来指定输出的文件名,但此时不能再指定扩展名,因为扩展名是由 outformat 指定的,下面我们将文件名指定为 my_diagram:

from diagrams import Diagram
from diagrams.aws.compute import EC2

with Diagram("Simple Diagram", filename="my_diagram"):
    EC2("web")

也使用 show 参数来禁用文件自动打开,默认是True:

from diagrams import Diagram
from diagrams.aws.compute import EC2

with Diagram("Simple Diagram", show=False):
    EC2("web")

它还允许自定义Graphviz点属性选项,比如:

from diagrams import Diagram
from diagrams.aws.compute import EC2

graph_attr = {
    "fontsize": "45",
    "bgcolor": "transparent"
}

with Diagram("Simple Diagram", show=False, graph_attr=graph_attr):
 EC2("web")

graph_attr, node_attr 和 edge_attr 都是支持的。具体可查看链接: https://www. graphviz.org/doc/info/a ttrs.html .

二、节点

Node是展现节点或系统组成的第二个对象。

基础使用

节点是表示单个系统组件对象的抽象概念。 节点对象由三部分组成:提供者、资源类型和名称。

from diagrams import Diagram
from diagrams.aws.compute import EC2

with Diagram("Simple Diagram"):
 EC2("web")

在上面的例子中,EC2 是由 aws 提供者提供的计算资源类型的节点。

可以以类似的方式使用其他节点对象,例如:

# aws 资源
from diagrams.aws.compute import ECS, Lambda
from diagrams.aws.database import RDS, ElastiCache
from diagrams.aws.network import ELB, Route53, VPC
...

# azure 资源
from diagrams.azure.compute import FunctionApps
from diagrams.azure.storage import BlobStorage
...

# 阿里云 资源
from diagrams.alibabacloud.compute import ECS
from diagrams.alibabacloud.storage import ObjectTableStore
...

# gcp 资源
from diagrams.gcp.compute import AppEngine, GKE
from diagrams.gcp.ml import AutoML 
...

# k8s 资源
from diagrams.k8s.compute import Pod, StatefulSet
from diagrams.k8s.network import Service
from diagrams.k8s.storage import PV, PVC, StorageClass
...

# oracle 资源
from diagrams.oci.compute import VirtualMachine, Container
from diagrams.oci.network import Firewall
from diagrams.oci.storage import Filestorage, Storagegateway

数据流

你可以通过使用以下运算符: >>、<< 和 - 连接节点来表示数据流。

  • >>:从左到右连接节点。
  • <<:从右向左连接节点。
  • -:无方向连接节点。无方向的。
from diagrams import Diagram
from diagrams.aws.compute import EC2
from diagrams.aws.database import RDS
from diagrams.aws.network import ELB
from diagrams.aws.storage import S3

with Diagram("Web Services", show=False):
    ELB("lb") >> EC2("web") >> RDS("userdb") >> S3("store")
    ELB("lb") >> EC2("web") >> RDS("userdb") <> EC2("web")) - EC2("web") >> RDS("userdb")

使用 - 和任何 shift 运算符时要注意,可能会因为运算优先级导致非预期的结果。

图展现的顺序跟代码声明的顺序相反。

你可以使用direction参数来改变数据流方向,默认是LR。

TB、BT、LR 和 RL 都是可选的。

from diagrams import Diagram
from diagrams.aws.compute import EC2
from diagrams.aws.database import RDS
from diagrams.aws.network import ELB

with Diagram("Workers", show=False, direction="TB"):
    lb = ELB("lb")
    db = RDS("events")
    lb >> EC2("worker1") >> db
    lb >> EC2("worker2") >> db
    lb >> EC2("worker3") >> db
    lb >> EC2("worker4") >> db
    lb >> EC2("worker5") >> db

组数据流

上面的worker示例有很多冗余流。这种情况下,你可以使用组数据流将节点分组到一个列表中,以便所有节点同时连接到其他节点。

from diagrams import Diagram
from diagrams.aws.compute import EC2
from diagrams.aws.database import RDS
from diagrams.aws.network import ELB

with Diagram("Grouped Workers", show=False, direction="TB"):
    ELB("lb") >> [EC2("worker1"),
                  EC2("worker2"),
                  EC2("worker3"),
                  EC2("worker4"),
                  EC2("worker5")] >> RDS("events")

不能直接连接两个列表,因为在Python中不允许在列表之间进行移位/算术操作

三、集群

集群允许你将节点分组放在一个独立的组中。

基础使用

Cluster表示本地群集上下文。

你可以使用cluster类创建集群上下文。你还可以将集群中的节点连接到集群外的其他节点。

from diagrams import Cluster, Diagram
from diagrams.aws.compute import ECS
from diagrams.aws.database import RDS
from diagrams.aws.network import Route53

with 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

嵌套集群

嵌套集群也是可以使用的。

from diagrams import Cluster, Diagram
from diagrams.aws.compute import ECS, EKS, Lambda
from diagrams.aws.database import Redshift
from diagrams.aws.integration import SQS
from diagrams.aws.storage import S3

with 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

嵌套没有深度限制。你可以随意创建任意深度的嵌套集群。

四、边

边表示节点之间的边。

基础使用

Edge是一个对象,表示具有某些附加属性的节点之间的连接。

一个edge对象包含三个属性:label、color和style,它们对应相应的graphviz的边属性。

from diagrams import Cluster, Diagram, Edge
from diagrams.onprem.analytics import Spark
from diagrams.onprem.compute import Server
from diagrams.onprem.database import PostgreSQL
from diagrams.onprem.inmemory import Redis
from diagrams.onprem.logging import Fluentd
from diagrams.onprem.monitoring import Grafana, Prometheus
from diagrams.onprem.network import Nginx
from diagrams.onprem.queue import Kafka

with Diagram(name="Advanced Web Service with On-Premise (colored)", show=False):
    ingress = Nginx("ingress")

    metrics = Prometheus("metric")
    metrics << Edge(color="firebrick", style="dashed") << Grafana("monitoring")

    with Cluster("Service Cluster"):
        grpcsvc = [
            Server("grpc1"),
            Server("grpc2"),
            Server("grpc3")]

    with Cluster("Sessions HA"):
        master = Redis("session")
        master - Edge(color="brown", style="dashed") - Redis("replica") << Edge(label="collect") <> Edge(color="brown") >> master

    with Cluster("Database HA"):
        master = PostgreSQL("users")
        master - Edge(color="brown", style="dotted") - PostgreSQL("slave") << Edge(label="collect") <> Edge(color="black") >> master

    aggregator = Fluentd("logging")
    aggregator >> Edge(label="parse") >> Kafka("stream") >> Edge(color="black", style="bold") >> Spark("analytics")

    ingress >> Edge(color="darkgreen") <> Edge(color="darkorange") >> aggregator