大数跨境

软件架构风格:单体架构、模块化架构、微服务架构,哪个更适合你

软件架构风格:单体架构、模块化架构、微服务架构,哪个更适合你 索引目录
2025-06-26
2
导读:关注【索引目录】服务号,更多精彩内容等你来探索!

关注【索引目录】服务号,更多精彩内容等你来探索!

作为软件开发人员,我们可以使用多种工具来构建软件,以使用 Java 构建的软件为例,我们有方法,一旦我们有了一堆相关的方法,我们就可以将它们分组到类中,这些类可以分组到包中,这些包可以在模块中外部化。

软件架构是关于所有这些工具如何链接以及彼此之间的关系。

在本文中,我们将介绍最常用的软件架构风格,包括单体架构和微服务架构,然后我们将介绍另一种被认为是两种架构之间的中间立场的架构,称为模块化(模块化单体架构)

什么是单体应用程序



在单体式架构中,只有一个代码库,所有内容都作为一个单元进行打包和部署,

单片应用程序使用的数据存储在单个数据库中。

对于处理中等数据量的中小型应用程序,这种架构风格仍然非常实用和高效,以下是它的一些优点:

  • 易于开发:开发人员可以轻松了解应用程序的流程
  • 易于重构和调试:使用现代 IDE,这两项任务变得简单而直接
  • 低延迟:调用发生在属于同一进程的函数之间,没有网络开销

当应用程序需要处理的职责、库和数据量不断增长时,整体式架构的问题就开始出现,在这些情况下,我们应该处理:

  • 扩展效率低下:如果应用程序的某个部分流量很大,那么解决这个问题的唯一选择就是扩展整个应用程序及其所有部分
  • 团队并行化复杂:这种架构风格很容易导致业务领域之间耦合,使用相同代码库的团队之间可能会发生合并冲突。
  • 弹性差:如果应用程序的一部分崩溃,整个应用程序就会崩溃。

什么是微服务应用程序



这一切都是关于在责任方面独立部署小型软件,在单独的进程上运行并通过网络调用相互通信。

每个软件都应该有自己的数据库。

引入这种架构风格是为了克服单片应用程序变大时所面临的挑战。以下是它的一些优点:

  • 选择性可扩展性:可以仅扩展负载较高的服务,而不是整个系统。
  • 清晰的上下文边界:每个服务都应该专注于特定的业务领域并有明确的职责,这种分离使得可维护性变得更加容易。
  • 容错和增强的弹性:如果一项服务出现故障,其他服务仍然可以继续处理收到的请求。

微服务并不是免费提供这些好处的,它们也有缺点:

  • 延迟增加:服务之间的通信涉及网络调用,谁说网络,就说潜在的不可靠性、延迟、超时
  • 额外的开发复杂性:采用这种方式,开发人员必须付出额外的努力来处理服务发现、数据一致性和分布式日志记录/跟踪/监控

微服务风格比单体风格更好吗?

大多数时候,我们对单体架构持负面看法,而对微服务印象很好,这通常是因为微服务是由科技行业中占主导地位的公司推动的,然而,这种观点非常主观。

单体架构在低层级上非常有用,我们可以用一个小团队来开发简单的应用程序,并且非常高效,而不需要微服务的开销。

模块化整体结构(Modulith):中间地带



除了单体架构和微服务之外,还有另一种架构风格,称为模块化单体架构(modulith),它专注于将应用程序分解为业务模块,这些模块都在同一个代码库中,因此它仍然是一个单体架构,但是它们的源代码不会纠缠在一起,模块之间彼此隔离,并且它们之间的通信通过 API 或事件进行。

当谈论模块化单体中的模块时,我们指的是业务模块,而不是 Java 模块或构建工具模块,它们是完全不同的概念

这种风格的有趣之处在于,您可以同时受益于整体式架构和微服务的优势:

  • 应用程序的结构清晰,使开发人员更容易理解流程。
  • 源代码集中在一个地方,可以利用这一点来利用 IDE 的重构和调试功能
  • 没有网络开销,意味着低延迟。
  • 模块之间有清晰的上下文边界

您无法从微服务优势中获得的东西是:

  • 容错(弹性)
  • 选择性可扩展性

如何在 Java 中实现模块化

在 Java 中,实现 moduliths 主要有三种方法:

  • 每个业务模块的套餐
  • 根据业务模块构建工具模块(使用 Maven 或 Gradle)
  • 每个业务模块的 Java 模块 (JPMS)

使用包进行模块化

这是最简单、最常见的方法。应用程序仍然是单个传统的 Java 模块,每个业务模块都放在一个专门的 Java 包中(例如 com.myapp.orders、com.myapp.billing 等)。

这种方式实现起来比较简单,但是它在编译时和运行时都没有对业务模块之间进行严格的界限划分,并且为了保证模块之间的低耦合度,需要进行代码审查,如果没有规范,项目很容易变成一个混乱的整体。

使用 Maven/Gradle 多模块项目进行模块化

在这种方法中,每个业务模块都被拆分成各自的 Maven 或 Gradle 项目。每个模块都会编译成一个单独的 JAR 文件,并且模块依赖关系会在构建配置中明确声明。

这种方法的好处在于,编译时隔离由构建工具强制执行,模块只能访问其依赖的模块,这减少了最终形成混乱的整体的可能性,然而在运行时,所有项目的所有类都可以通过反射在所有类中使用。

使用 JPMS 进行模块化

使用 JPMS(在 Java 9 中引入),每个业务模块都放置在自己的 Java 模块中,并使用 module-info.java 文件进行定义。

JPMS 在编译时和运行时强制上下文之间的隔离,但是与 Spring Boot 等现代框架集成有点复杂


关注【索引目录】服务号,更多精彩内容等你来探索!


【声明】内容源于网络
0
0
索引目录
索引目录是一家专注于医疗、技术开发、物联网应用等领域的创新型公司。我们致力于为客户提供高质量的服务和解决方案,推动技术与行业发展。
内容 0
粉丝 0
索引目录 索引目录是一家专注于医疗、技术开发、物联网应用等领域的创新型公司。我们致力于为客户提供高质量的服务和解决方案,推动技术与行业发展。
总阅读0
粉丝0
内容0