分布式单体的六大病症


当公式的组织架构及其代码被拆分以后,但仍然存在紧密耦合时,就会出现分布式单体。这已经成为一个问题,因为系统的规模增加,单体的所有部分都需要一起管理,这会放慢开发速度并增加任何变化的风险。

能够识别何时处理分布式单体很重要:

1. 锁定部署
当两个服务需要一起部署时,它们是耦合的。如果它们在一个单体中,这很容易管理。但是,如果它们是实际上应该独立管理的独立服务,部署可能会变得缓慢和痛苦。我们可以通过识别耦合的原因并重构我们的解决方案来解决这个问题。

如果这两个服务使用共享代码,则解决方案可以重组代码以共享一个单独管理的库。如果他们使用共享基础设施,这可能意味着将服务拆分到不同的主机上。

2.版本耦合
如果服务 A 直接调用服务 B 的一个版本,则每次更新服务 B 时,我们都需要更新服务 A 的配置。这种更改耦合会使管理两个应用程序的生命周期变得复杂,但这是可能的。

理想情况下,服务 A 应该调用服务 B 的端点,该端点不是特定版本,并且也由服务 B 管理。这通常可以通过使用 CNAMES 的 DNS 来完成,如下所示:
A1.domain.com > 调用 > B.domain.com > B1.domain.com
而不是:
A1.domain.com > 调用 > B1.domain.com

3. 双向依赖
如果服务 A 调用服务 B 并且服务 B 调用服务 A,则很难测试对任一系统的更改。发生这种情况时,我们可以选择同时更改整个环境,测试通过旧版和新版软件发送到的事件,或者在如何路由消息方面显着增加复杂性。

4.共享数据库访问
当两个服务共享相同的数据库访问权限时,无需直接调用服务即可轻松地从另一个域中提取数据。这可能导致在数据库层连接的耦合服务。当服务修改它自己的数据库结构时,它不应该影响任何其他服务。反之如果是这样,那么服务是耦合的。

共享数据库以节省管理工作并没有错,但这应该通过安全性进行严格控制以防止耦合。使用 Postgres 执行此操作的常用方法是为每个服务使用单独的用户和模式。如果一个服务想要访问另一个服务的数据,它应该直接调用下游服务。

5. 共享队列
与共享数据库访问导致耦合的方式相同,共享队列也是如此。如果两个服务直接与一个共享队列通信,那么任何一个服务都无法安全地修改、更改或重定向消息,而不会有破坏这两个服务的风险。

应尽可能避免共享队列,并且任何队列都应由单个服务拥有并且不暴露给其他服务。

6.企业服务总线
企业服务总线 (ESB) 是另一种常见的数据存储模式,类似于共享数据库和共享队列,但规模更大。ESB 旨在允许通过中央总线发送和接收任何消息。这意味着一旦服务向总线发送消息,就不清楚谁在使用该消息,正在使用它做什么,以及它是否成功。这些问题不容易解决,这意味着我们的系统不仅会与其他系统耦合,而且会超出我们可能意识到的范围。

概括
无论您的系统架构如何,您都应该能够清楚地确定您的系统是单体、微服务还是分布式单体。通过共享部署、共享数据和双向依赖识别与其他服务的耦合在此过程中至关重要。这样做将使我们能够构建我们的架构,这样我们就可以避免最终成为分布式单体。