模块化单体架构是一种非常流行的架构方法。 它们结合了模块化和单片设计的优点。
模块化单体试图解决单体和微服务架构的缺点。
我经常看到的单片架构的一个问题是组件之间的紧密耦合。
这会导致系统不同部分之间的依赖关系。
模块化单体通过明确定义的模块边界和通信模式实施更好的架构实践。
但一个不容忽视的方面是模块之间的数据隔离。
数据隔离确保模块是独立且松散耦合的。
今天,我将向您展示模块化单体的四种数据隔离方法:
单独的表格
单独的架构
单独的数据库
不同的持久性
为什么数据隔离很重要?
让我们首先了解为什么数据隔离在模块化单体架构中很重要。
模块化单体对数据完整性有严格的规则:
每个模块只能访问自己的表
模块之间不共享表或对象
只允许在同一模块的表之间进行联接
模块化单体内部的模块应该是独立的。 每个模块处理自己的数据。 其他模块可以使用模块的公共 API 访问该数据。
这种设计有什么好处?
保持模块彼此隔离有助于模块化和松耦合。 这样可以更轻松地向系统引入新的更改。 当组件松散耦合时,意外的副作用较少。
如果使用的是关系数据库,则仍可以保持引用完整性。 提取表时删除外键不是问题。
第 1 级 - 独立表
最简单的解决方案是在数据库级别不进行隔离。 所有模块的表都位于一个数据库中。 确定哪些表属于哪个模块并不容易。
我只是为了完整起见而提及这种方法。
但是,这种方法适用于特定的应用程序大小。
但是,您拥有的表越多,就越难将它们隔离在模块之间。
您可以通过在表之间添加逻辑隔离来改进这一点。
级别 2 - 单独的架构
对数据库中的相关表进行分组是引入逻辑隔离的一种方式。 您可以使用数据库架构来实现这一点。 每个模块都有一个唯一的架构,其中包含模块的表。
现在,很容易区分哪个模块包含哪些表。
实现此目的的一种简单方法是使用多个 EF Core 数据库上下文。
您还可以引入规则来防止从其他模块查询数据。 例如,您可以使用体系结构测试来实现这一点。
在构建模块化单体架构时,我总是从逻辑数据隔离开始。
但是,如果这还不够呢?
级别 3 - 独立数据库
下一个数据隔离级别是将每个模块的数据移动到单独的数据库中。 与使用架构的数据隔离相比,此方法具有更多的约束。
如果您需要在模块之间设置严格的数据隔离规则,则可以采用这种方法。 但是,缺点是操作更加复杂。 您必须管理多个数据库的基础结构。
但是,这是提取模块的绝佳一步。
首先,将要提取的模块的表移动到单独的数据库中。 这也迫使您解决模块之间的任何数据库耦合问题。 将表移动到单独的数据库后,即可提取模块。
我们能否进一步实现模块数据隔离?
级别 4 - 不同的持久性
谁说必须对所有模块使用相同的数据库类型?
我大部分时间都在使用关系 (SQL) 数据库。 关系数据库令人惊叹,可以解决各种各样的问题。 但有时,文档或图形数据库是更好的解决方案。
这里的想法是相似的:您正在使用单独的数据库进行数据隔离。
但是,您可以引入不同的数据库类型来解决特定问题。 例如,可以将关系数据库用于一个模块。 以及另一个模块的图形或列存储数据库。 您还必须在应用程序中维护不同的持久性模型。
对于您的用例来说,这可能是一个值得的权衡。 但这需要仔细规划。
总结
如果您不需要立即使用微服务,模块化单体架构是非常好的选择。 将应用程序开发为在系统内部具有不同边界的单体。 您仍然可以灵活地提取模块并迁移到微服务。但是,使用模块化单体架构可以加快开发速度。
模块必须遵守一些规则。 他们只能访问自己的表。 它们不能与其他模块共享表。 而且他们不能直接查询其他模块的表。 这些规则有助于在模块之间强制实施数据隔离。
但是,您仍然必须在数据库级别实现数据隔离。
有四个选项可供选择:
单独的表格
单独的架构
单独的数据库
不同的持久性