← 返回蜂巢洞察

如何使用Python制作系统设计图

制作系统架构设计图是技术文档中非常重要的一部分。随着系统复杂性的增加,团队内部的信息清晰度就变得更加重要了。 但是,使用类似画布的工具从零开始绘制图表并不总是高效的。 幸运的是,还有一种替代方法,那就是采用“将图表视为代码”这种方式来创建图表。在这种方法中,你需要使用预定义的语法来描述图表的各个组成部分,而不是直接进行绘图操作。 目录 将图表视为代码的优势 先决条件与安装方法 什么是图表? 你的第一个图表 如何连接节点与数据流 数据流的分类与整理 集群概念 边与连接关系 总结 将图表视为代码的优势: 变更内容可以通过版本控制进行追踪。 由于无需从零开始绘制,也不需要手动调整格式,因此能够节省时

制作系统架构设计图是技术文档中非常重要的一部分。随着系统复杂性的增加,团队内部的信息清晰度就变得更加重要了。

但是,使用类似画布的工具从零开始绘制图表并不总是高效的。

幸运的是,还有一种替代方法,那就是采用“将图表视为代码”这种方式来创建图表。在这种方法中,你需要使用预定义的语法来描述图表的各个组成部分,而不是直接进行绘图操作。

目录

将图表视为代码的优势:

  • 变更内容可以通过版本控制进行追踪。

  • 由于无需从零开始绘制,也不需要手动调整格式,因此能够节省时间。

  • 大多数采用“将图表视为代码”技术的工具都支持数据库、存储桶、负载均衡器等常见的技术图标。

  • 在持续集成/持续交付流程中,或者通过编写代码来生成文档时,都可以自动创建图表。

先决条件与安装方法

在本教程中,你将学习如何使用Python的Diagrams库来绘制图表。基本需要的先决条件包括:

  • Python 3.7或更高版本

  • 用于安装Python包的pip

  • 你的操作系统上已经安装了Graphviz,以便生成图表输出图像

  • 还需要安装以下Python包:

    pip install diagrams
    
  • 需要一个终端环境,以便运行如下命令:

    python diagram.py
    

什么是图表?

Diagrams是一个Python库,它允许你用Python代码来绘制云系统架构图。该库支持Azure、GCP、AWS等多种云服务提供商。

学习完本教程后,你将能够理解这个图表是如何制作出来的:

使用AWS图标绘制的视频处理平台系统架构图

你的第一个图表

首先,确保你的配置已经满足所有先决条件。然后创建一个扩展名为.py的Python文件,并将以下代码添加到其中:

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

with Diagram("Practice Architecture"):
    EC2("api-server")

让我们逐行了解这段代码的含义。

首先,我们导入了Diagram类:

from diagrams import Diagram

可以把Diagram想象成一块空白的画布,你在上面绘制的所有内容都属于这个画布。Diagram代表整个图示的结构框架。

接下来我们导入了一种节点类型。节点代表着你的架构中的某个组成部分。例如,ECS、Lambda函数、Service以及防火墙都属于资源类型。

from diagrams.aws.compute import EC2

一个节点对象由三部分组成:提供者、资源类型以及名称。在上面的例子中,EC2是一种属于compute资源类型的节点,而这种节点是由aws提供者提供的。

这段代码表示从AWS的计算服务组中导入EC2节点类型。我们将使用这个类来创建EC2节点。

diagrams.aws.compute就是导入路径,它指明了EC2节点对应的文件位置。

diagrams
└── aws
    └── compute
        └── EC2

你可以访问这里,了解更多关于不同提供者的官方节点类型信息。

假设你想在图示中使用AWS提供的Analytics组件,首先你需要从上面列出的节点类型中找到Analytics。你的导入语句应该写成from diagrams.aws.analytics import Analytics。

然后使用with Diagram创建图示结构:

with Diagram("Practice Architecture"):

回到上面的例子,这段代码会创建一个名为Practice Architecture的图示。所有在with Diagram括号内定义的内容都属于这个图示。

现在我们来创建一个节点:

EC2("api-server")

这样就会创建一个标签为api-server的EC2节点。

最后,运行这段代码。如果你将Python文件保存为test.py,就可以使用python test.py来执行它。Diagrams会自动在当前文件夹中生成图像文件:

使用Nodes对象创建的单个节点示例

简而言之,整个流程如下:

使用Diagrams库和Graphviz生成图像的流程图请注意,你所描述的是基础设施的配置方式,而不是手动绘制这些结构图。你并不需要考虑如何绘制或排列各种图标,只需编写代码 `EC2("api-server")`, Diagrams 会负责处理后续的渲染工作。 我们可以稍微扩展上面的例子,添加两个 EC2 实例:
from diagrams import Diagram
from diagrams.aws.compute import EC2

with Diagram("Practice Architecture"):
    EC2("api-server")
    EC2("worker")
使用 Nodes 对象创建的两个节点的示例 你可以将节点实例赋值给变量,这样就可以方便地引用它们了。 下面的例子展示了如何进行变量赋值:
from diagrams import Diagram
from diagrams.aws.compute import EC2

with Diagram("Practice Architecture"):
    api_server = EC2("api-server")
    worker = EC2("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("The three directions"):
    load_balancer = ELB("load-balancer")
    web_server = EC2("web-server")
    database = RDS("database")
    backup_server = EC2("backup-server")

    load_balancer >> web_server
    web_server << database
    database - backup_server
请注意节点之间的连接关系:
# 用从左到右的箭头表示负载均衡器与 Web 服务器之间的连接
load_balancer >> web_server
    
# 用从右到左的箭头表示 Web 服务器与数据库之间的连接
web_server << database

# 用直线表示数据库与备份服务器之间的连接
database - backup_server
使用三种方式连接节点——从左到右的箭头、从右到左的箭头以及无方向性的连接

分组数据流

你也可以使用 Python 列表将一个节点与多个节点连接起来,这样就不需要逐一地将各个节点相互连接了。 假设你想实现这样的架构:
                    ┌──► web-1 ───┐
负载均衡器 ──────┼──► web-2 ───┼──► 数据库
                    └──► web-3 ───┘

首先,创建一个负载均衡器:

load_balancer = ELB("entry-point")

然后创建多个服务器。不必像这样分别创建三个变量:

server1 = EC2("web-1") server2 = EC2("web-2") server3 = EC2("web-3")

你可以将它们放在一个Python列表中:

web_servers = [ EC2("web-1"), EC2("web-2"), EC2("web-3") ]

然后这样将负载均衡器与服务器列表连接起来:

load_balancer >> web_servers

这样一来,就无需手动编写如下代码了:

load_balancer >> web Servers[0] load_balancer >> web Servers[1] load_balancer >> webServers[2]

现在,将整个服务器列表与数据库连接起来:

web_servers >> database

这种做法有助于减少代码中的冗余部分,同时也有助于处理那些重复出现的组件,比如多个Pod、工作节点等等。

完整的代码如下所示:

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应用"): load_balancer = ELB("entry-point") web_servers = [ EC2("web-1"), EC2("web-2"), EC2("web-3") ] database = RDS("orders-db") load_balancer >> web Servers >> database 示意图显示了一个负载均衡器连接着三个Web服务器,而这些Web服务器又连接到数据库

集群

你可以使用“集群”将相关的节点放在同一个标记框内。不过,你仍然可以将集群内的节点与外部的节点进行连接。

进行分组是必要的,因为这样才能清楚地表明哪些元素属于同一组。这样做有助于表达诸如以下概念:

  • 应用层

  • 数据库层

  • 可用区

  • 区域

  • 环境

  • 微服务组

  • 工作节点组

创建集群的语法如下:

with Cluster("集群名称"):

在此语句下面缩进编写的所有内容都属于该集群。

以下是一个演示如何使用集群的例子:

from diagrams import Diagram, Cluster from diagrams.aws.compute import EC2 from diagrams.aws.database import RDS with Diagram("购物平台"): with Cluster("应用层"): apps = [ EC2("app-1"), EC2("app-2") ] with Cluster("数据库层"): primary_db = RDS("primary-db") replica_db = RDS("read-replica") apps >> primary_db primary_db - replica_db

一个用于连接两个不同集群的示例

使用这种语法,也可以嵌套集群:

with Cluster("Production"):

    with Cluster("Backend"):

        with Cluster("API"):
            ...

让我们来看一个更具体的例子,其中包含了集群的嵌套结构:

from diagrams import Diagram, Cluster
from diagrams.aws.compute import EC2
from diagrams.aws.database import RDS

with Diagram("Production Platform"):

    with Cluster("Production Region"):

        with Cluster("Application Tier"):

            with Cluster("API Servers"):
                api1 = EC2("api-1")
                api2 = EC2("api-2")

        database = RDS("main-db")

        api1 >> database
        api2 >> database

这个例子展示了一个名为Production Platform的结构,其中包含了Production Region,而Production Region又包含了Application Tier。在Application Tier中,进一步划分出了两个API服务器。生产区域内还部署了一个独立的RDS数据库,这两个API服务器都连接到了这个数据库。

通过将不同的集群相互嵌套在一起,就可以实现更复杂的结构。请参考下面的代码示例:

with Cluster("Production Region"):

        with Cluster("Application Tier"):

            with Cluster("API Servers"):
                api1 = EC2("api-1")
                api2 = EC2("api-2")
一个关于集群嵌套的示例

边

边提供了一种连接节点的另一种方式。与普通的>>或<<<不同,边允许你添加标签、颜色和样式等属性。

之前你是这样使用的:

from diagrams import Diagram

如果要使用边,就需要添加以下代码:

from diagrams import Diagram, Edge

现在,我们可以用一条边将app与database连接起来:

# 为边添加标签
app >> Edge(label="SQL queries") >> database

这样,就用一条标有“SQL queries”标签的边将app与database连接起来了。

为连接两个节点的边添加标签

你还可以自定义边的颜色:

app >> Edge(label="SQL", color="red") >> database
将某条边设置为红色

您也可以修改边的样式:

app >> Edge(style="虚线") >> database
使用虚线连接两个节点

还有一些其他的边样式可供选择:

Edge(style="点线")
Edge/style="粗体")

下面的示例结合了多种边的样式:

from diagrams import Diagram, Edge
from diagrams.aws.compute import EC2
from diagrams.aws.database import RDS

with Diagram("支付服务"):
    api = EC2("payment-api")
    database = RDS("payments-db")

    api >> Edge(
        label="支付记录",
        color="darkgreen",
        style="虚线"
    ) >> database
示例:结合边的样式、颜色和标签

请注意,您也可以使用<&><和-来表示边的连接关系。

总结

通过本教程,您学习了如何利用“图谱即代码”的方法来创建具有意义且格式统一的图表,并了解这些图表如何在不同团队之间得到有效使用。这种方法能够帮助您提高工作效率,同时也不会影响图表的质量或开发/维护工作的质量。

在本教程中,您主要使用了AWS相关的组件。您可以在这份指南中了解其他可用的工具提供商,并根据自己的需求来创建图表。

非常感谢您阅读到这篇文章的结尾。如果您从这篇文章中学到了什么,欢迎将这些知识分享给他人。

保持联系,继续您的学习之旅吧!

您可以通过以下方式与我保持联系:

  • LinkedIn:我会分享与Linux、网络安全及DevOps相关的内容。如果您觉得这篇文章有帮助,请在LinkedIn上留下您的推荐。

  • Twitter:我会发布产品发布的预热信息以及一些幕后花絮。

祝您编码愉快!

相关文章

技术实践

如何在不编写Recharts样板代码的情况下,将shadcn图表添加到Next.js应用程序中

在任务列表中,创建图表似乎是一项简单的任务。但当你打开 Recharts 的文档后,就会发现其实每个图表的设置都需要耗费不少精力:需要为标签和颜色配置相应的对象、设置坐标轴、添加工具提示、设计图例、选择适合深色模式的配色方案,还要确保图表容器能够正确地调整大小。我们大多数人都会从上一个项目中复制这些设置内容,然后重新命名相关变量即可。 shadcn/ui 图表组件在一定程度上减轻了这些工作负担。它为 Recharts 提供了与主题风格相匹配的配色方案和工具提示功能,但用户仍然需要手动编写每个图表的代码。 因此,我开发了 ChartCN——这个免费且开源的 shadcn 图表生成工具 。你只需粘

阅读全文
技术实践

Radicle揭示了那些会暴露私有代码仓库的关键缺陷,而这些缺陷实际上是以明文形式存在的。

Radicle在其网络协议中发现了两处严重的安全漏洞,这些漏洞会影响所有版本的节点的正常运行,从而导致数据保密性遭到破坏。攻击者可以利用这些漏洞直接访问私有存储库中的数据,并伪造节点的身份进行恶意操作。由于存在架构上的缺陷,建议立即停止所有涉及明文传输的操作。为修复这些漏洞,需要更换为新的协议(Iroh),但这会导致旧版本与新版本之间的不兼容问题。 作者:Olimpiu Pop

阅读全文
技术实践

WebRTC是如何实现扩展性的?信号传输机制、NAT穿越技术,以及Mesh架构、SFU架构与MCU架构之间的权衡取舍

Web实时通信(WebRTC)是一种开放标准,浏览器利用这一标准直接相互发送音频、视频和数据。无需任何插件或原生应用程序,只需要每个浏览器都已内置的API即可。 WebRTC负责处理媒体数据的传输过程:一旦两台设备建立连接,从编解码器的选择到数据的编码与传输,所有相关环节都由WebRTC来处理。不过,它并不负责设备之间的连接建立过程。 本文探讨了构成WebRTC标准的三个API,分析了为什么信号传输机制和NAT穿透技术不属于这些API的范畴,介绍了一种大规模部署的信号服务器实现方案,并讨论了影响媒体数据传输能力的关键因素,如Mesh网络结构、选择性转发单元以及多点会议单元等。 目录 基础构成:

阅读全文
技术实践

理解CAP定理:系统设计中的一致性、可用性与分区容错性

1999年,埃里克·布鲁尔提出了一种理论,这一理论在随后几十年里极大地影响了分布式系统的设计方式。他指出,任何分布式数据存储系统最多只能同时满足三个属性中的两个:一致性、可用性和分区容错性。 两年后,塞思·吉尔伯特和南希·林奇正式证明了这一观点,这一理论后来被称为CAP定理。 所有那些需要在多台机器上存储数据的分布式数据库、云服务或系统,都必须在这三个属性之间做出选择。理解这些属性的具体含义、为什么不能同时满足全部三个属性,以及在实际应用中应该如何做出这种选择,对于任何负责构建或运营大规模系统的工程师来说,都是至关重要的基础知识。 目录 先决条件 三个属性 为什么不能同时满足全部三个属性 真正

阅读全文