单体架构是构建应用程序的传统方式。这种软件架构原则既有优点也有缺点。一方面,它可以带来愉悦。另一方面,它可能会导致失望。让我们回顾一下它在软件架构中的位置。


单体架构审查

#yyds干货盘点#——如何理解单体架构_数据库

       典型的单体架构如上图所示。它的关键特征是所有内容(用户服务、飞行服务和计费服务)都位于单个交付物(在Spring Boot 的情况下为 jar 文件)中。这些服务紧密耦合(尽管它们具有完全不同的功能)并使用相同的数据库。

       图为现在最常用的方法。实际上,在单体架构中,UI部分可以与支持的服务一起打包。因此,UI、User Service、Flight Service和Billing Service都位于一个单一的交付物中。

        出于扩展目的,部署了多个相同的可交付单元。负载均衡器负责将请求路由到已部署的单体服务。


单体架构的优势
  • 开发简单。单体式方法是构建应用程序的标准方法。不需要额外的知识。所有源代码都集中在一处,可以快速理解。
  • 调试简单。调试过程很简单,因为所有代码都位于一处。您可以轻松地跟踪请求的流程并找到问题。
  • 测试的简单性。您只测试一项没有任何依赖项的服务。一切通常都很清楚。
  • 部署简单。只应部署一个部署单元(例如jar文件)。没有依赖关系。在 UI 与后端代码打包在一起的情况下,您没有任何重大更改。一切都在一个地方存在和变化。
  • 应用程序演化的简单性。基本上,从业务逻辑的角度来看,应用程序没有任何限制。如果您需要一些新功能的数据,它已经在那里了。
  • 横切关注点和自定义仅使用一次。您应该只关心一次横切一次。比如安全、日志、异常处理、监控、tomcat参数的选择和设置、数据源连接池的设置等。
  • 新团队成员入职的简单性。源代码位于一处。新团队成员可以轻松调试一些功能流程并熟悉应用程序。
  • 在应用的早期阶段成本低。所有源代码都位于一个地方,打包在一个单独的部署单元中并部署。什么可以更容易?基础设施成本和开发成本都没有开销。

由于这些优势,单体架构通常用于应用程序开发的早期阶段。原因如下:

  • 该应用程序的主要功能是盈利。因此,快速实施一些 POC(概念验证)解决方案以在现实世界中验证应用程序非常重要。此外,将客户带到系统中也很重要。改进措施可以在未来实施。
  • 在开发的早期阶段,需求通常是不明确的。当需求不明确时,很难创建有意义的架构。真正的客户可以在某些功能已经运行后定义业务需求。

当应用程序成功时,单体架构的问题开始出现。原因很简单:应用的增长。通常,经过一段时间后,由于下一个原因,单体应用程序会更改为另一个应用程序。


单体架构的缺点
  • 发展速度缓慢。最简单的缺点与CI/CD 管道有关。想象一下包含大量服务的单体应用。这个整体中的每个服务都包含为每个拉取请求执行的测试。即使对于源代码的微小更改,您也应该等待大量时间(例如 1 小时)以使您的管道成功。当管道由于某种原因失败时会发生什么?你再等等。所有服务都位于一个地方。团队的规模很大。当您的同事合并他们的更改时会发生什么?您变基/合并并再次等待。
  • 高代码耦合。当然,您可以在存储库中保持清晰的服务结构。但是,实践表明,最终您至少会在几个地方得到意大利面条代码。因此,系统变得更难理解,尤其是对于新的团队成员。
  • 不能使用代码所有权。该系统正在增长。合乎逻辑的步骤是在多个团队之间分配职责。例如,一个团队可以在Flight Service上工作,另一个团队可以在Billing Service 上工作。但是,这些服务之间没有界限。一支球队可以影响另一支球队。
  • 测试变得更加困难。即使是很小的变化也会对系统产生负面影响。因此,需要对完整的单体服务进行回归。
  • 性能问题。潜在地,您可以在出现性能问题的情况下扩展整个单体服务。但是如何处理数据库呢?单一数据库用于所有服务。您可以开始优化数据库查询或使用只读副本。但是,这种类型的优化是有限制的。
  • 基础设施的成本。如果出现性能问题,您应该扩展整个单体服务。它为应用程序的可操作性带来了额外的成本。
  • 遗留技术。想象一下,您的应用程序是用 Java 8 编写的。将带有多个服务的整个整体迁移到 Java 11 需要多长时间?如何处理带来新功能所需的任务?可能永远不会迁移应用程序。
  • 缺乏灵活性。使用单体架构,您对单体架构中使用的技术非常了解。您不能使用其他工具,即使它们更适合手头的问题。
  • 部署问题。即使是很小的变化也需要重新部署整个单体。


总结

       由于快速开发、测试和调试的简单性以及成本,单体架构是小型应用程序的最佳选择。然而,当系统增长时,它可能成为业务的障碍,应该演变成另一种形式。

在下一篇文章中,将回顾微服务架构。