[第二部:容器和微服务架构] (7)分布式数据管理的挑战与解决方案

本文涉及的产品
数据管理 DMS,安全协同 3个实例 3个月
推荐场景:
学生管理系统数据库
云原生 API 网关,700元额度,多规格可选
简介: [第二部:容器和微服务架构] (7)分布式数据管理的挑战与解决方案

挑战1:如何定义每个微服务的边界


定义微服务边界可能是任何人遇到的第一个挑战。每个微服务都必须是应用程序的一部分,每个微服务都应该是自主的,具有它所传递的所有好处和挑战。但是你如何确定这些界限呢?

首先,您需要关注应用程序的逻辑域模型和相关数据。尝试在同一个应用程序中识别分离的数据孤岛和不同的上下文。每个上下文可以有不同的业务语言(不同的业务术语)。上下文应该独立定义和管理。在这些不同上下文中使用的术语和实体听起来可能类似,但您可能会发现,在特定上下文中,一个业务概念与另一个业务概念用于不同的上下文中,甚至可能有不同的名称。例如,用户可以在身份或成员关系上下文中被称为用户,在CRM上下文中被称为客户,在订购上下文中被称为买方,等等。

为每个上下文标识具有不同域的多个应用程序上下文之间的边界的方式,正是如何标识每个业务微服务及其相关域模型和数据的边界。您总是试图最小化这些微服务之间的耦合。本指南稍后将在《为每个微服务标识域模型边界》一节中详细介绍此标识和域模型设计。


挑战2:如何创建从多个微服务检索数据的查询


第二个挑战是如何实现从多个微服务检索数据的查询,同时避免从远程客户端应用程序与微服务进行聊天。例如,移动应用程序中的一个屏幕需要显示篮子、目录和用户标识微服务所拥有的用户信息。另一个例子是一个复杂的报表,其中包含位于多个微服务中的多个表。正确的解决方案取决于查询的复杂性。但无论如何,如果您想提高系统通信的效率,就需要一种聚合信息的方法。最流行的解决方案如下。


API网关。


对于来自拥有不同数据库的多个微服务的简单数据聚合,建议使用称为API网关的聚合微服务。但是,在实现这个模式时需要小心,因为它可能是系统中的一个瓶颈,并且可能违反微服务自治的原则。为了减少这种可能性,您可以拥有多个细粒度API网关,每个网关侧重于系统的垂直“部分”或业务区域。API网关模式将在后面的API网关部分中进行更详细的解释。


带有查询/读取表的CQRS(命令和查询责任隔离)


从多个微服务聚合数据的另一个解决方案是物化视图模式。在这种方法中,您可以预先(在实际查询发生之前准备非规范化的数据)生成一个只读表,其中包含多个微服务所拥有的数据。该表的格式适合客户端应用程序的需要。

考虑一下类似移动应用程序的屏幕。如果只有一个数据库,则可以使用SQL查询将该屏幕的数据拉到一起,该查询执行涉及多个表的复杂连接。但是,如果您有多个数据库,并且每个数据库都属于不同的微服务,则无法查询这些数据库并创建SQL联接。复杂的查询成为一个挑战。您可以使用CQRS方法来解决需求,您可以在一个仅用于查询的不同数据库中创建一个非规范化的表。该表可以专门为复杂查询所需的数据设计,应用程序屏幕所需的字段与查询表中的列之间具有一对一的关系。它也可用于报告目的。


这种方法不仅解决了最初的问题(如何跨微服务查询和连接),而且与复杂的连接相比,它还大大提高了性能,因为您已经在查询表中拥有应用程序所需的数据。当然,对查询/读取表使用命令和查询责任分离(CQRS)意味着需要额外的开发工作,您需要接受最终的一致性。尽管如此,协作场景(或竞争场景,取决于视角)中的性能和高可伸缩性要求是您应该对多个数据库应用cqr的地方。


中央数据库中的“冷数据”。


对于可能不需要实时数据的复杂报表和查询,一种常见的方法是将“热数据”(来自微服务的事务数据)作为“冷数据”导出到仅用于报表的大型数据库中。中央数据库系统可以是一个基于大数据的系统,比如Hadoop,一个基于Azure SQL数据仓库的数据仓库,甚至是一个只用于报表的SQL数据库(如果大小不是问题的话)。


请记住,这个集中式数据库只用于不需要实时数据的查询和报告。原始的更新和事务,作为您的真相来源,必须在您的微服务数据。同步数据的方式可以是使用事件驱动的通信(下一节将介绍)或使用其他数据库基础结构导入/导出工具。如果使用事件驱动的通信,那么集成过程将类似于前面为CQRS查询表所描述的传播数据的方式。


但是,如果您的应用程序设计涉及不断聚合来自多个微服务的信息以进行复杂的查询,则这可能是设计错误的征兆-微服务应尽可能与其他微服务隔离。(这不包括总是应该使用冷数据中心数据库的报表/分析)经常出现此问题可能是合并微服务的一个原因。您需要在每个微服务的演进和部署的自主性与强依赖性、内聚性和数据聚合之间取得平衡。


挑战3:如何跨多个微服务实现一致性


如前所述,每个微服务拥有的数据是该微服务的私有数据,只能使用其微服务API访问。因此,一个挑战是如何实现端到端业务流程,同时保持多个微服务之间的一致性。


为了分析这个问题,让我们看一个来自eShopOnContainers参考应用程序的示例。目录微服务维护所有产品的信息,包括产品价格。Basket microservice管理用户添加到购物篮中的产品项目的时间数据,其中包括添加到购物篮时的项目价格。当产品的价格在目录中更新时,该价格也应该在保存同一产品的活动篮中更新,另外,系统可能应该警告用户,说某个特定项目的价格自从添加到其篮中后已经发生了变化。


在这个应用程序的假设整体版本中,当products表中的价格发生变化时,catalog子系统可以简单地使用ACID事务来更新篮子表中的当前价格。

但是,在基于微服务的应用程序中,产品表和篮子表由各自的微服务拥有。任何微服务都不应该在自己的事务中包括另一个微服务拥有的表/存储,甚至在直接查询中也不应该包括,如图4-9所示。


微服务禁止直接访问另一个微服务中的表


Catalog microservice不应该直接更新Basket表,因为Basket表属于Basket microservice。为了更新Basket microservice,Catalog microservice应该使用可能基于异步通信(如集成事件(基于消息和事件的通信))的最终一致性。这就是eShopOnContainers引用应用程序如何跨微服务执行这种类型的一致性。


如CAP定理所述,您需要在可用性和ACID 强一致性之间进行选择。大多数基于微服务的场景要求可用性和高可伸缩性,而不是强一致性。任务关键型应用程序必须保持正常运行,开发人员可以通过使用处理弱一致性或最终一致性的技术来解决强一致性问题。这是大多数基于微服务的架构所采用的方法。

此外,ACID风格或两阶段提交事务不仅违反微服务原则;大多数NoSQL数据库(如Azure Cosmos DB、MongoDB等)不支持两阶段提交事务,这在分布式数据库场景中是典型的。然而,维护跨服务和数据库的数据一致性是必不可少的。这个挑战还涉及到当某些数据需要冗余时(例如,当您需要在目录微服务和篮子微服务中包含产品名称或描述时),如何在多个微服务中传播更改的问题。


解决这个问题的一个很好的方法是使用事件驱动通信和发布和订阅系统所连接的微服务之间的最终一致性。本指南后面的异步事件驱动通信一节将介绍这些主题。


挑战4:如何设计跨越微服务边界的通信


跨越微服务边界进行通信是一个真正的挑战。在这种情况下,通信并不是指应该使用什么协议(HTTP和REST、AMQP、消息传递等等)。相反,它解决了您应该使用什么样的通信方式,特别是您的微服务应该如何耦合。根据耦合的级别,当发生故障时,该故障对系统的影响将有很大的不同。


在像基于微服务的应用程序这样的分布式系统中,有这么多工件在移动,并且有跨多个服务器或主机的分布式服务,组件最终将失败。部分故障甚至更大的中断都会发生,因此您需要考虑到这种分布式系统中的常见风险,设计您的微服务和它们之间的通信。


一种流行的方法是实现基于HTTP(REST)的微服务,因为它们很简单。基于HTTP的方法是完全可以接受的;这里的问题与您如何使用它有关。如果使用HTTP请求和响应只是为了与来自客户端应用程序或API网关的微服务交互,那就没问题了。但是,如果您跨微服务创建长链的同步HTTP调用,并跨其边界进行通信,就好像微服务是单片应用程序中的对象一样,那么您的应用程序最终将遇到问题。


例如,假设您的客户机应用程序对单个微服务进行HTTP API调用,就像对微服务进行排序一样。如果顺序微服务在同一请求/响应周期内使用HTTP调用其他微服务,则创建一个HTTP调用链。一开始听起来可能很合理。然而,在沿着这条路走下去时,需要考虑的要点有:


  • 阻塞和低性能。由于HTTP的同步特性,原始请求在所有内部HTTP调用完成之前不会得到响应。想象一下,如果这些调用的数量显著增加,同时对微服务的一个中间HTTP调用被阻塞。结果是性能受到影响,并且随着额外的HTTP请求的增加,总体可伸缩性将受到指数级的影响。

  • 将微服务与HTTP耦合。业务微服务不应与其他业务微服务耦合。理想情况下,他们不应该“知道”其他微服务的存在。如果应用程序依赖于耦合微服务(如示例所示),则几乎不可能实现每个微服务的自治。

  • 任何一个微服务出现故障。如果实现了一个由HTTP调用链接的微服务链,那么当任何一个微服务失败(最终它们将失败)时,整个微服务链都将失败。应设计一个基于微服务的系统,以便在部分故障期间尽可能继续工作。即使实现了使用指数退避或断路器机制重试的客户端逻辑,HTTP调用链越复杂,实现基于HTTP的故障策略就越复杂。


事实上,如果您的内部微服务是通过创建所述的HTTP请求链进行通信的,那么可以认为您有一个单片应用程序,但它是基于进程间HTTP而不是进程内通信机制的应用程序。


因此,为了强制微服务自治并具有更好的弹性,您应该尽量减少跨微服务的请求/响应通信链的使用。建议您只使用异步交互进行微服务间通信,可以使用异步消息和基于事件的通信,也可以使用(异步)HTTP轮询,独立于原始HTTP请求/响应周期。


异步通信的使用将在本指南后面的“异步微服务集成实施微服务的自治和基于异步消息的通信”一节中详细说明。


额外资源

相关实践学习
MySQL基础-学生管理系统数据库设计
本场景介绍如何使用DMS工具连接RDS,并使用DMS图形化工具创建数据库表。
相关文章
|
22天前
|
Kubernetes Cloud Native 微服务
探索云原生技术:容器化与微服务架构的融合之旅
本文将带领读者深入了解云原生技术的核心概念,特别是容器化和微服务架构如何相辅相成,共同构建现代软件系统。我们将通过实际代码示例,探讨如何在云平台上部署和管理微服务,以及如何使用容器编排工具来自动化这一过程。文章旨在为开发者和技术决策者提供实用的指导,帮助他们在云原生时代中更好地设计、部署和维护应用。
|
1月前
|
运维 Kubernetes Cloud Native
云原生技术:容器化与微服务架构的完美结合
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术以其灵活性和高效性成为企业的新宠。本文将深入探讨云原生的核心概念,包括容器化技术和微服务架构,以及它们如何共同推动现代应用的发展。我们将通过实际代码示例,展示如何在Kubernetes集群上部署一个简单的微服务,揭示云原生技术的强大能力和未来潜力。
|
22天前
|
Java 开发者 微服务
从单体到微服务:如何借助 Spring Cloud 实现架构转型
**Spring Cloud** 是一套基于 Spring 框架的**微服务架构解决方案**,它提供了一系列的工具和组件,帮助开发者快速构建分布式系统,尤其是微服务架构。
142 68
从单体到微服务:如何借助 Spring Cloud 实现架构转型
|
21天前
|
运维 监控 持续交付
微服务架构解析:跨越传统架构的技术革命
微服务架构(Microservices Architecture)是一种软件架构风格,它将一个大型的单体应用拆分为多个小而独立的服务,每个服务都可以独立开发、部署和扩展。
150 36
微服务架构解析:跨越传统架构的技术革命
|
19天前
|
Java Nacos Sentinel
Spring Cloud Alibaba:一站式微服务解决方案
Spring Cloud Alibaba(简称SCA) 是一个基于 Spring Cloud 构建的开源微服务框架,专为解决分布式系统中的服务治理、配置管理、服务发现、消息总线等问题而设计。
176 13
Spring Cloud Alibaba:一站式微服务解决方案
|
5天前
|
运维 监控 Java
为何内存不够用?微服务改造启动多个Spring Boot的陷阱与解决方案
本文记录并复盘了生产环境中Spring Boot应用内存占用过高的问题及解决过程。系统上线初期运行正常,但随着业务量上升,多个Spring Boot应用共占用了64G内存中的大部分,导致应用假死。通过jps和jmap工具排查发现,原因是运维人员未设置JVM参数,导致默认配置下每个应用占用近12G内存。最终通过调整JVM参数、优化堆内存大小等措施解决了问题。建议在生产环境中合理设置JVM参数,避免资源浪费和性能问题。
25 3
|
17天前
|
运维 Kubernetes 调度
阿里云容器服务 ACK One 分布式云容器企业落地实践
阿里云容器服务ACK提供强大的产品能力,支持弹性、调度、可观测、成本治理和安全合规。针对拥有IDC或三方资源的企业,ACK One分布式云容器平台能够有效解决资源管理、多云多集群管理及边缘计算等挑战,实现云上云下统一管理,提升业务效率与稳定性。
|
1月前
|
Kubernetes Cloud Native Docker
云原生之旅:从传统架构到容器化服务的演变
随着技术的快速发展,云计算已经从简单的虚拟化服务演进到了更加灵活和高效的云原生时代。本文将带你了解云原生的概念、优势以及如何通过容器化技术实现应用的快速部署和扩展。我们将以一个简单的Python Web应用为例,展示如何利用Docker容器进行打包和部署,进而探索Kubernetes如何管理这些容器,确保服务的高可用性和弹性伸缩。
|
28天前
|
Kubernetes Cloud Native 持续交付
容器化、Kubernetes与微服务架构的融合
容器化、Kubernetes与微服务架构的融合
47 1
|
28天前
|
运维 Kubernetes Docker
深入理解容器化技术及其在微服务架构中的应用
深入理解容器化技术及其在微服务架构中的应用
59 1