“我读到 C4 最适合单体架构,不太适合分布式架构”......这是我经常看到的说法,但事实并非如此。C4 模型是基于一小组抽象的分层图表集合。这里没有什么比 UML、ArchiMate 或临时白板草图更适合分布式架构的了。问题实际上是工具之一,我们无法考虑过去的静态 PNG 文件。

如果您遵循康威定律,并且有不同的团队拥有分布式架构的不同部分,那么这篇文章可能不适合您。这篇文章的真正目标是构建分布式单体的团队——一个团队,大量可单独部署的微服务和/或 lambdas,锁步部署等。这些架构往往在 C4 模型_容器_级别有很多元素和关系,因此很难创建一个不杂乱且易于理解的综合容器图。这条推文很好地总结了情况。

“使用无服务器,您正在部署 UML 协作图!”

任何包含 20 多个元素(可能更少)的图表都会很快变得复杂,从而更难讲述你想要讲述的故事。复杂的架构会导致复杂的图表。

一个例子

这是一个过于简单的例子,(请不要创建一个分布式架构,它实际上只是一个脆弱的同步服务相互通信的链!),但我想用这个例子来说明一些关于图表的观点。许多团队最初会通过绘制一个显示其整体架构的图表来解决此问题 - 可能会显示构成软件系统的所有容器,以及它们的外部依赖项。

[](https://res.cloudinary.com/practicaldev/image/fetch/s--CYKSgbf_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads。 s3.amazonaws.com/uploads/articles/oexr9e9din2zem9c4opy.png)

当然,这张图还不错,而且这种方法适用于较小的软件系统。一旦你开始使用 10 项服务、20 项服务或 100 项服务,它就会很快分崩离析。尽管理想情况下我们希望创建一个显示所有内容的单一图表,但在许多情况下这并不可行。这种制图方法无法扩展。不过,您确实有一些选择。

选项 1:创建多个较小的图表

其中一个选项是创建多个图表,显示整个故事的一个子集。您可以创建图表来显示单个域、有界上下文、业务能力、特性等。或者,您可以创建图表以专注于单个服务及其直接传入/传出耦合。这是一个专注于“服务 1”而不是显示所有容器的示例。

[](https://res.cloudinary.com/practicaldev/image/fetch/s--9oDcgYpk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads。 s3.amazonaws.com/uploads/articles/h1eciygoq4342pnzb5c3.png)

这样做确实会丢失一些“大图”,但是这张图更容易理解,因为它的范围更加有限。这种方法的问题与我在Diagrams as code 2.0中概述的问题相同......我们将需要在多个图表中重复元素/关系,并且我们需要一种策略来使它们在事情发生时保持同步改变。

这导致了工具,以及图表与建模。我之前说过:我们需要停止使用通用图表工具来绘制软件架构图(Visio 等),并且在使用 PlantUML、C4-PlantUML、Mermaid 等制作图表之前,我们也应该仔细考虑。

上图专注于“服务 1”,使用任何“模型 + 视图”工具都可以轻松创建。例如,使用 Structurizr DSL,一旦定义了整体模型,就可以像这样创建上图:

views {
  container softwareSystem {
    include user ->service1->
  }
}

进入全屏模式 退出全屏模式

这就是说,“创建一个容器视图,显示用户、服务 1 以及直接连接到服务 1 的任何内容”。它也通过Structurizr CLI 导出命令与多种图表格式兼容。这是上图的 PlantUML 版本,由相同的 Structurizr DSL 代码创建。

[](https://res.cloudinary.com/practicaldev/image/fetch/s--W0MqKBk---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads .s3.amazonaws.com/uploads/articles/2fmtid113hrrkjuqhi1s.png)

“模型+视图”工具提供了一种快速简便的方法来讲述模型中的不同故事,同时保持所有生成的图表同步。 Structurizr DSL 和 CLI 是免费和开源的,加上过去 20 多年的任何优秀 UML 工具也应该提供此功能,尽管用户体验非常不同。建模并不新鲜,我们真的不应该为了变得“敏捷”而匆忙放弃它。

选项 2:使用不同的可视化格式

凭借我们可用的所有计算能力,团队“只希望在 Confluence 中嵌入 PNG 图像”仍然让我感到惊讶。当然,还可以使用其他文档工具。

传统的静态图非常适合交流,但它们不应该是您工具箱中的唯一工具。一旦您放弃对静态 PNG 图像的痴迷并跨越鸿沟,您可能会发现还有其他可视化格式更适合帮助您讲述故事。

例如,交互式力导向图更适合显示和探索大量数据。诚然,像D3.js这样的东西有一个陡峭的学习曲线,但这使得这相对简单。

[](https://res.cloudinary.com/practicaldev/image/fetch/s--MBoKCXOn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads。 s3.amazonaws.com/uploads/articles/puhc4q0i8fewgsa63wyu.png)

(是的,我并没有忘记发布交互式图表的静态屏幕截图的讽刺意味,所以这里是交互式版本的链接)

或者,有像Ilograph这样的工具,它提供了一种使用交互式 UI 导航模型的方法。

[](https://res.cloudinary.com/practicaldev/image/fetch/s--np-DXobc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/jp5ymivglkm31b6enhdy.png)

[](https://res.cloudinary.com/practicaldev/image/fetch/s--BZFft6Zw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads。 s3.amazonaws.com/uploads/articles/sm02csvqvlben1pyuw3v.png)

(如果您不喜欢手动编写 Ilograph 的 YAML 定义,可以使用Structurizr DSL 到 Ilograph 导出)

总结

总之,C4 模型并不比其他任何用于绘制分布式架构的替代方案更适合。在一个更大的单体应用程序中绘制组件图时也会遇到同样的问题。这些问题与图表的大小和复杂性有关。如果一个有十几个盒子的图表很难理解,就不要画一个有十几个盒子的图表!

相反,从图表切换到建模,想想你想要讲述的故事是什么,看看技术如何帮助你实现这个目标。Diagrams as code 2.0是一种非常强大的方法,如果您愿意跳过图表制作的鸿沟。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐