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

简介: [第二部:容器和微服务架构] (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请求/响应周期。


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


额外资源

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
相关文章
|
11月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
1478 3
|
10月前
|
存储 安全 Java
管理 Spring 微服务中的分布式会话
在微服务架构中,管理分布式会话是确保用户体验一致性和系统可扩展性的关键挑战。本文探讨了在 Spring 框架下实现分布式会话管理的多种方法,包括集中式会话存储和客户端会话存储(如 Cookie),并分析了它们的优缺点。同时,文章还涵盖了与分布式会话相关的安全考虑,如数据加密、令牌验证、安全 Cookie 政策以及服务间身份验证。此外,文中强调了分布式会话在提升系统可扩展性、增强可用性、实现数据一致性及优化资源利用方面的显著优势。通过合理选择会话管理策略,结合 Spring 提供的强大工具,开发人员可以在保证系统鲁棒性的同时,提供无缝的用户体验。
217 0
|
人工智能 安全 Java
智慧工地源码,Java语言开发,微服务架构,支持分布式和集群部署,多端覆盖
智慧工地是“互联网+建筑工地”的创新模式,基于物联网、移动互联网、BIM、大数据、人工智能等技术,实现对施工现场人员、设备、材料、安全等环节的智能化管理。其解决方案涵盖数据大屏、移动APP和PC管理端,采用高性能Java微服务架构,支持分布式与集群部署,结合Redis、消息队列等技术确保系统稳定高效。通过大数据驱动决策、物联网实时监测预警及AI智能视频监控,消除数据孤岛,提升项目可控性与安全性。智慧工地提供专家级远程管理服务,助力施工质量和安全管理升级,同时依托可扩展平台、多端应用和丰富设备接口,满足多样化需求,推动建筑行业数字化转型。
451 5
|
负载均衡 NoSQL 算法
Redisson分布式锁数据一致性解决方案
通过以上的设计和实现, Redisson能够有效地解决分布式环境下数据一致性问题。但是, 任何技术都不可能万无一失, 在使用过程中还需要根据实际业务需求进行逻辑屏障的设计和错误处理机制的建立。
611 48
|
Java Nacos Sentinel
Spring Cloud Alibaba:一站式微服务解决方案
Spring Cloud Alibaba(简称SCA) 是一个基于 Spring Cloud 构建的开源微服务框架,专为解决分布式系统中的服务治理、配置管理、服务发现、消息总线等问题而设计。
3329 13
Spring Cloud Alibaba:一站式微服务解决方案
|
监控 Kubernetes Cloud Native
基于阿里云容器服务Kubernetes版(ACK)的微服务架构设计与实践
本文介绍了如何基于阿里云容器服务Kubernetes版(ACK)设计和实现微服务架构。首先概述了微服务架构的优势与挑战,如模块化、可扩展性及技术多样性。接着详细描述了ACK的核心功能,包括集群管理、应用管理、网络与安全、监控与日志等。在设计基于ACK的微服务架构时,需考虑服务拆分、通信、发现与负载均衡、配置管理、监控与日志以及CI/CD等方面。通过一个电商应用案例,展示了用户服务、商品服务、订单服务和支付服务的具体部署步骤。最后总结了ACK为微服务架构提供的强大支持,帮助应对各种挑战,构建高效可靠的云原生应用。
|
关系型数据库 MySQL Docker
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
1004 24
|
人工智能 安全 Java
微服务引擎 MSE:打造通用的企业级微服务架构
微服务引擎MSE致力于打造通用的企业级微服务架构,涵盖四大核心内容:微服务技术趋势与挑战、MSE应对方案、拥抱开源及最佳实践。MSE通过流量入口、内部流量管理、服务治理等模块,提供高可用、跨语言支持和性能优化。此外,MSE坚持开放,推动云原生与AI融合,助力企业实现无缝迁移和高效运维。
814 1
|
Kubernetes 安全 数据安全/隐私保护
云卓越架构:容器安全最佳实践
本次分享由阿里云智能集团解决方案架构师张玉峰主讲,主题为“云卓越架构:容器安全最佳实践”。内容涵盖容器安全的挑战、云原生容器安全架构及典型场景。首先分析了容器安全面临的问题,如镜像漏洞和权限管理。接着介绍了容器安全架构的五个维度:身份权限管理、配置安全检查、运行时防护、镜像安全检测及发布的安全管控。最后通过具体场景展示了容器身份与权限管理、密钥管理、运行时防入侵等最佳实践,强调了安全左移的重要性,确保从开发到运行的全生命周期安全覆盖。
|
Java 关系型数据库 数据库
微服务SpringCloud分布式事务之Seata
SpringCloud+SpringCloudAlibaba的Seata实现分布式事务,步骤超详细,附带视频教程
1220 1

热门文章

最新文章