【AICon】探索RAG 技术在实际应用中遇到的挑战及应对策略!AICon精华内容已上线73%>>> 了解详情
写点什么

微服务架构:拆分单体应用的难点

  • 2020-04-24
  • 本文字数:3864 字

    阅读完需:约 13 分钟

微服务架构:拆分单体应用的难点

拆分单体应用为服务的难点

从表面上看,通过定义与业务能力或子域相对应的服务来创建微服务架构的策略看起来很简单。但是,你可能会遇到几个障碍:


  • 网络延迟。

  • 同步进程间通信导致可用性降低。

  • 在服务之间维持数据一致性。

  • 获取一致的数据视图。

  • 上帝类阻碍了拆分。

  • 让我们来看看每个问题,先从网络延迟开始。

网络延迟

网络延迟是分布式系统中一直存在的问题。你可能会发现,对服务的特定分解会导致两个服务之间的大量往返调用。有时,你可以通过实施批处理 API 在一次往返中获取多个对象,从而将延迟减少到可接受的数量。但在其他情况下,解决方案是把多个相关的服务组合在一起,用编程语言的函数调用替换昂贵的进程间通信。

同步进程间通信导致可用性降低

另一个需要考虑的问题是如何处理进程间通信而不降低系统的可用性。例如,实现 createOrder()操作最常见的方式是让 Order Service 使用 REST 同步调用其他服务。这样做的弊端是 REST 这样的协议会降低 Order Service 的可用性。如果任何一个被调用的服务处在不可用的状态,那么订单就无法创建了。有时候这可能是一个不得已的折中,但是在第 3 章中学习异步消息之后,你就会发现其实有更好的办法来消除这类同步调用产生的紧耦合并提升可用性。

在服务之间维持数据一致性

另一个挑战是如何在某些系统操作需要更新多个服务中的数据时,仍旧维护服务之间的数据一致性。例如,当餐馆接受订单时,必须在 Kitchen Service 和 Delivery Service 中同时进行更新。Kitchen Service 会更改 Ticket 的状态。Delivery Service 安排订单的交付。这些更新都必须以原子化的方式完成。


传统的解决方案是使用基于两阶段提交(two phase commit)的分布式事务管理机制。但正如你将在第 4 章中看到的那样,对于现今的应用程序而言,这不是一个好的选择,你必须使用一种非常不同的方法来处理事务管理,这就是 Saga。Saga 是一系列使用消息协作的本地事务。Saga 比传统的 ACID 事务更复杂,但它们在许多情况下都能工作得很好。Saga 的一个限制是它们最终是一致的。如果你需要以原子方式更新某些数据,那么它必须位于单个服务中,这可能是分解的障碍。

获取一致的数据视图

分解的另一个障碍是无法跨多个数据库获得真正一致的数据视图。在单体应用程序中,ACID 事务的属性保证查询将返回数据库的一致视图。相反,在微服务架构中,即使每个服务的数据库是一致的,你也无法获得全局一致的数据视图。如果你需要一些数据的一致视图,那么它必须驻留在单个服务中,这也是服务分解所面临的问题。幸运的是,在实践中这很少带来真正的问题。

上帝类阻碍了拆分

分解的另一个障碍是存在所谓的上帝类。上帝类是在整个应用程序中使用的全局类。上帝类通常为应用程序的许多不同方面实现业务逻辑。它有大量字段映射到具有许多列的数据库表。大多数应用程序至少有一个这样的上帝类,每个类代表一个对领域至关重要的概念:银行账户、电子商务订单、保险政策,等等。因为上帝类将应用程序的许多不同方面的状态和行为捆绑在一起,所以将使用它的任何业务逻辑拆分为服务往往都是一个不可逾越的障碍。


Order 类是 FTGO 应用程序中上帝类的一个很好的例子。这并不奇怪:毕竟 FTGO 的目的是向客户提供食品订单。系统的大多数部分都涉及订单。如果 FTGO 应用程序具有单个领域模型,则 Order 类将是一个非常大的类。它将具有与应用程序的许多不同部分相对应的状态和行为。图 6 显示了使用传统建模技术创建的 Order 类的结构。



图 6 Order 这个上帝类承载了太多的职责


如你所见,Order 类具有与订单处理、餐馆订单管理、送餐和付款相对应的字段及方法。由于一个模型必须描述来自应用程序的不同部分的状态转换,因此该类还具有复杂的状态模型。在目前情况下,这个类的存在使得将代码分割成服务变得极其困难。


一种解决方案是将 Order 类打包到库中并创建一个中央 Order 数据库。处理订单的所有服务都使用此库并访问访问数据库。这种方法的问题在于它违反了微服务架构的一个关键原则,并导致我们特别不愿意看到的紧耦合。例如,对 Order 模式的任何更改都要求其他开发团队同步更新和重新编译他们的代码。


另一种解决方案是将 Order 数据库封装在 Order Service 中,该服务由其他服务调用以检索和更新订单。该设计的问题在于这样的一个 Order Service 将成为一个纯数据服务,成为包含很少或没有业务逻辑的贫血领域模型(anemic domain model)。这两种解决方案都没有吸引力,但幸运的是,DDD 提供了一个好的解决方案。


更好的方法是应用 DDD 并将每个服务视为具有自己的领域模型的单独子域。这意味着 FTGO 应用程序中与订单有关的每个服务都有自己的领域模型及其对应的 Order 类的版本。Delivery Service 是多领域模型的一个很好的例子。如图 7 所示为 Order,它非常简单:取餐地址、取餐时间、送餐地址和送餐时间。此外,DeliveryService 使用更合适的 Delivery 名称,而不是称之为 Order。



图 7 Delivery Service 的领域模型


Kitchen Service 有一个更简单的订单视图。它的 Order 版本就是一个 Ticket(后厨工单)。如图 8 所示,Ticket 只包含 status、requestedDeliveryTime、prepareByTime 以及告诉餐馆准备的订单项列表。它不关心消费者、付款、交付等这些与它无关的事情。



图 8 Kitchen Service 的领域模型


Order Service 具有最复杂的订单视图,如图 9 所示。即使它有相当多的字段和方法,它仍然比原始版本的那个 Order 上帝类简单得多。



图 9 Order Service 的领域模型


每个领域模型中的 Order 类表示同一 Order 业务实体的不同方面。FTGO 应用程序必须维持不同服务中这些不同对象之间的一致性。例如,一旦 OrderService 授权消费者的信用卡,它必须触发在 Kitchen Service 中创建 Ticket。同样,如果 Kitchen Service 拒绝订单,则必须在 Order Service 中取消订单,并且为客户退款。在第 4 章中,我们将学习如何使用前面提到的事件驱动机制 Saga 来维护服务之间的一致性。


除了造成一些技术挑战以外,拥有多个领域模型还会影响用户体验。应用程序必须在用户体验(即其自己的领域模型)与每个服务的领域模型之间进行转换。例如,在 FTGO 应用程序中,向消费者显示的 Order 状态来自存储在多个服务中的 Order 信息。这种转换通常由 API Gateway 处理,将在第 8 章中讨论。尽管存在这些挑战,但在定义微服务架构时,必须识别并消除上帝类。


我们现在来看看如何定义服务 API。

定义服务 API

到目前为止,我们有一个系统操作列表和一个潜在服务列表。下一步是定义每个服务的 API:也就是服务的操作和事件。存在服务 API 操作有以下两个原因:首先,某些操作对应于系统操作。它们由外部客户端调用,也可能由其他服务调用。另次,存在一些其他操作用以支持服务之间的协作。这些操作仅由其他服务调用。


服务通过对外发布事件,使其能够与其他服务协作。第 4 章将描述如何使用事件来实现 Saga,这些 Saga 可以维护服务之间的数据一致性。第 7 章将讨论如何使用事件来更新 CQRS 视图,这些视图支持有效的查询。应用程序还可以使用事件来通知外部客户端。例如,可以使用 WebSockets 将事件传递给浏览器。


定义服务 API 的起点是将每个系统操作映射到服务。之后确定服务是否需要与其他服务协作以实现系统操作。如果需要协作,我们将确定其他服务必须提供哪些 API 才能支持协作。首先来看一下如何将系统操作分配给服务。

把系统操作分配给服务

第一步是确定哪个服务是请求的初始入口点。许多系统操作可以清晰地映射到服务,但有时映射会不太明显。例如,考虑使用 noteUpdatedLocation()操作来更新送餐员的位置。一方面,因为它与送餐员有关,所以应该将此操作分配给 Courier Service。另一方面,它是需要送餐地点的 DeliveryService。在这种情况下,将操作分配给需要操作所提供信息的服务是更好的选择。在其他情况下,将操作分配给具有处理它所需信息的服务可能是有意义的。表 4 显示了 FTGO 应用程序中的哪些服务负责哪些操作。



表 4 FTGO 应用程序的系统操作映射到具体的服务


把操作分配给服务后,下一步是确定在处理每一个系统操作时,服务之间如何交互。


确定支持服务协作所需要的 API


某些系统操作完全由单个服务处理。例如,在 FTGO 应用程序中,Consumer Service 完全独立地处理 createConsumer()操作。但是其他系统操作跨越多个服务。处理这些请求之一所需的数据可能分散在多个服务周围。例如,为了实现 createOrder()操作,Order Service 必须调用以下服务以验证其前置条件并使后置条件成立:


Consumer Service:验证消费者是否可以下订单并获取其付款信息。


Restaurant Service:验证订单行项目,验证送货地址和时间是否在餐厅的服务区域内,验证订单最低要求,并获得订单行项目的价格。


Kitchen Service:创建 Ticket(后厨工单)。


Accounting Service:授权消费者的信用卡。


同样,为了实现 acceptOrder()系统操作,Kitchen Service 必须调用 Delivery Service 来安排送餐员交付订单。表 2-3 显示了服务、修订后的 API 及协作者。为了完整定义服务 API,你需要分析每个系统操作并确定所需的协作。

总结

微服务中的服务是根据业务需求进行组织的,按照业务能力或者子域,而不是技术上的考量。


有两种分解模式:


  • 按业务能力分解,其起源于业务架构。

  • 基于领域驱动设计的概念,通过子域进行分解。


可以通过应用 DDD 并为每个服务定义单独的领域模型来消除上帝类,正是上帝类引起了阻碍分解的交织依赖项。


本文转载自技术锁话公众号。


原文链接:https://mp.weixin.qq.com/s/2qrEH2_ZwE0HD1M5bQ4i5A


2020-04-24 15:451211

评论

发布
暂无评论
发现更多内容

哈工大副校长刘挺访问度小满 推进人工智能等方面技术合作

科技热闻

Mac视频转码编辑工具 Compressor 4.7中文激活版 现已支持M3 Mac

Rose

Compressor Mac下载 Compressor破解版 Mac视频编码工具 Compressor for mac

三分钟搞懂Serverless,互联网个人创业者必备

凌览

node.js Serverless 独立开发者

代购系统独立站的未来发展前景

Noah

MySQL数据库中SQL语句分几类?

小齐写代码

初识 OpenCV

数新网络官方账号

OpenCV 计算机视觉

KeyShot 2023.3 Pro for mac(3D渲染和动画制作软件) v12.2.2激活版

mac

苹果mac Windows软件 KeyShot Pro 高级渲染和动画软件

企业服务大模型扎根生产一线,用友BIP为中国智造“再续新篇”!

用友BIP

企业大模型

高效会议指南:九种让你的会议更有价值的方法

PingCode

团队 会议

关于组态图和组态图设计

2D3D前端可视化开发

组态软件 组态 组态图库 组态界面 组态工具

KeyShot2023pro安装包 附KeyShot注册机 适用于Mac/win

Rose

KeyShot2023pro安装包 KeyShot 注册机 3D渲染和动画软件

畅捷通的 Serverless 探索实践之路

Serverless Devs

云计算 Serverless AIGC

Mac电脑强大的fcpx视频剪辑:Final Cut Pro 中文最新

胖墩儿不胖y

视频处理工具 编辑视频 视频编辑器 视频管理

​iOS Class Guard github用法、工作原理和安装详解及使用经验总结

RazorSQL for Mac(多功能SQL数据库管理器)v10.5.0注册激活版

影影绰绰一往直前

Final Cut Pro for Mac(fcpx视频剪辑)v10.7.0 中文版

Rose

mac软件下载 Final Cut Pro中文版 Final Cut Pro破解版 fcpx 视频剪辑软件

一起学Elasticsearch系列-脚本查询

Java随想录

Java 大数据 Elastic Search

RazorSQL for Mac(多功能SQL数据库管理器)支持M1/M2 v10.5.0注册激活版

Rose

数据库 RazorSQL下载 RazorSQL注册码

AnyGo for Mac(在iPhone / iPad上轻松模拟GPS位置)v6.9.0激活版

Rose

AnyGo中文版 AnyGo for Mac Mac虚拟机定位 GPS位置 AnyGo破解版

HarmonyOS开发案例分享:万能卡片也能用来玩游戏

HarmonyOS开发者

HarmonyOS

KaiwuDB 通过中国信通院“可信数据库”性能与稳定性评测

KaiwuDB

KaiwuDB 可信数据库

强大专业的设计排版工具Affinity Publisher 免激活最新

mac大玩家j

Mac软件 排版软件 排版工具

如何在 Mac 上创造一个纯 Windows 环境

Rose

Parallels Desktop

微软远程管理Microsoft Remote Desktop怎么样?好用吗?

Rose

Mac远程控制软件 microsoft remote desktop mac破解软件下载 微软远程管理

iMovie for Mac v10.4.0中文版 支持Macos14系统 兼容M3 Mac

Rose

iMovie Mac破解版 Mac视频剪辑工具 iMovie mac版 iMovie中文版下载

淘宝订单接口在电商行业中的重要性及其实践

Noah

记一次线上视频接口OOM问题

xfgg

Java

苹果Macos好玩的经典游戏推荐!

Rose

mac游戏 苹果mac游戏 Mac游戏推荐

Wireshark中的ARP协议包分析

小魏写代码

每日一题:LeetCode-41. 缺失的第一个正数

半亩房顶

面试 算法 数组 LeetCode 哈希表

石磊:以人为本,精细运营 ,企业招聘管理的下半场

用友BIP

智能招聘

微服务架构:拆分单体应用的难点_文化 & 方法_技术琐话_InfoQ精选文章