架构模式:每个服务独立的数据库

架构模式:每个服务独立的数据库

上下文

让我们假设您正在使用微服务架构模式开发在线商店应用程序。大多数服务需要在某种数据库中保存数据。例如,订单服务存储有关订单的信息,而客户服务存储有关客户的信息。

问题

微服务应用程序中的数据库体系结构是什么?

要点

  • 服务必须松散耦合,以便可以独立开发,部署和扩展

  • 某些业务事务必须强制执行跨多个服务的不变量。例如,下订单用例必须验证新订单不会超过客户的信用额度。其他业务事务,必须更新多个服务所拥有的数据。

  • 某些业务事务需要查询由多个服务拥有的数据。例如,查看可用信用使用必须查询客户以查找creditLimit和Orders以计算未结订单的总金额。

  • 某些查询必须连接由多个服务拥有的数据。例如,查找特定区域中的客户及其最近的订单需要客户和订单之间的联接。

  • 有时必须复制和分割数据库才能扩展。请参阅比例立方体。

  • 不同的服务有不同的数据存储要求。对于某些服务,关系数据库是最佳选择。其他服务可能需要NoSQL数据库,例如MongoDB,它擅长存储复杂的非结构化数据,或Neo4J,用于高效存储和查询图形数据。

解决方案

将每个微服务的持久数据保持为该服务的私有,并且只能通过其API访问。下图显示了此模式的结构。


服务的数据库实际上是该服务实现的一部分。它不能由其他服务直接访问。
有几种不同的方法可以将服务的持久数据保密。您不需要为每个服务配置数据库服务器。例如,如果您使用的是关系数据库,则选项为:

  • 每个服务的私有表 - 每个服务拥有一组只能由该服务访问的表
  • 每个服务架构 - 每个服务都有一个专用于该服务的数据库架构
  • Database-server-per-service  - 每个服务都有自己的数据库服务器。

每个服务的私有表和每个服务的模式具有最低的开销。每个服务使用一个模式很有吸引力,因为它使所有权更加清晰。某些高吞吐量服务可能需要自己的数据库服务器。

创建强制执行此模块化的障碍是一个好主意。例如,您可以为每个服务分配不同的数据库用户ID,并使用数据库访问控制机制,例如授予。如果没有某种障碍来强制执行封装,开发人员总会试图绕过服务的API并直接访问它的数据。

结果上下文

每个服务使用数据库具有以下好处:

  • 有助于确保服务松散耦合。对一个服务的数据库的更改不会影响任何其他服务。

  • 每个服务都可以使用最适合其需求的数据库类型。例如,执行文本搜索的服务可以使用ElasticSearch。操纵社交图的服务可以使用Neo4j。

每个服务使用数据库有以下缺点:

  • 实现跨多个服务的业务事务并不简单。由于CAP定理,最好避免分布式事务。而且,许多现代(NoSQL)数据库不支持它们。最佳解决方案是使用最终一致的事件驱动架构。服务在更新数据时发布事件。其他服务订阅事件并更新其数据作为响应。

  • 实现连接现在位于多个数据库中的数据的查询具有挑战性。有各种解决方案:

  • 应用程序端连接 - 应用程序执行连接而不是数据库。例如,服务(或API网关)可以通过首先从客户服务检索客户,然后查询订单服务以返回客户的最新订单来检索客户及其订单。

  • 命令查询责任隔离(CQRS) - 维护一个或多个包含来自多个服务的数据的物化视图。这些视图由订阅每个服务在更新其数据时发布的事件的服务保留。例如,在线商店可以通过维护加入客户和订单的视图来实现查询特定区域中的客户及其最近订单的查询。该视图由订阅客户和订单事件的服务更新。

  • 管理多个SQL和NoSQL数据库的复杂性

相关的模式

  • 微服务架构模式创造了对这种模式的需求
  • 事件驱动的体系结构模式是实现最终一致事务的有用方法
  • 命令查询责任隔离(CQRS)模式是实现复杂查询的有用方法
  • 共享数据库反模式描述了微服务共享数据库导致的问题

 

posted on 2019-08-02 16:59  yaofengspark  阅读(816)  评论(0编辑  收藏  举报

导航