微服务数据库

甜点

上下文:

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

订单表和顾客表

问题

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

强制要求

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

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

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

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

  • 有时必须复制和分割数据库才能扩展。

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

解决方案

将每个微服务的持久化数据保持为该服务的私有,并且只能通过其API访问。服务的事务只涉及其数据库。

下图显示了此模式的结构。

服务的数据库实际上是该服务实现的一部分。它不能由其他服务直接访问。

有几种不同的方法可以将服务的持久数据保密。您不需要为每个服务配置数据库服务器。例如,如果您使用的是关系数据数据库,则选项为:

  • 每个服务 私有表(Private tables One Service) - 每个服务拥有一组只能由该服务访问的表
  • 每个服务一个模式(One Schema One Service) - 每个服务都有一个专用于该服务的数据库模式
  • 每个服务一个数据库(One Database One Service) - 每个服务都有自己的数据库服务器。

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

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

结果背景

  • 每个服务使用数据库具有以下好处:
  • 有助于确保服务松散耦合。对一个服务的数据库的更改不会影响任何服务。
  • 每个服务都可以使用最适合其需求的数据库类型。例如,执行文本搜索的服务可以使用ElasticSearch。操作社交图的服务可以使用Neo4j。

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

  • 实现跨多个服务的业务事务并不简单。由于CAP定理,最好避免分布式事务。而且,许多现代(NoSQL)数据库不支持它们。最好的解决方式是使用Saga模式。服务在更新数据时发布事件。其他服务订阅事件并更新其数据作为响应。
  • 实现连接现在位于多个数据库中的数据的查询具有挑战性。
  • 管理多个SQL和NoSQL数据库的复杂性

有各种解决方案:

  • API组合 - 应用程序执行连接而不是数据库。例如,服务(或API网关)可以通过首先从客户服务检索客户,然后查询订单服务以返回客户的最新订单来检索客户及其订单。
  • 命令查询责任隔离(CQRS) - 维护一个或多个包含来自多个服务的数据的物化视图。视图由订阅每个服务在更新其数据时发布的事件的服务保留。例如,在线商店可以通过维护加入客户和订单的视图来实现查询特定区域中的客户及其最近订单的查询。该视图由订阅客户和订单事件的服务更新。

相关模式

------ 本文结束感谢您的阅读-------------
给我加点油吧!