微服务架构的流行设计模式
几十年来,应用程序一直使用整体架构构建;但是,许多人现在正在转向微服务架构。微服务架构为我们提供了更快的开发速度、可扩展性、可靠性、使用适合的最佳技术堆栈开发每个组件的灵活性等等。微服务架构依赖于可独立部署的微服务。每个微服务都有自己的业务逻辑和数据库,由特定的域上下文组成。每个服务的测试、增强和缩放独立于其他微服务。
但是,微服务架构也容易遇到自己的挑战和复杂性。为了解决最常见的挑战和问题,一些设计模式已经发展。在本文中,我们将介绍其中的一些。
基本设计模式
在典型的微服务架构中,有八种以上的必备设计模式可用于顺利开发。在本节中,我们将更详细地了解这些模式。我们根据正在创建的应用程序类型将它们分为两个部分 - 绿地或棕地。
绿地应用程序的设计模式
当我们从头开始构建应用程序时,我们可以自由地应用微服务架构所需的所有最新和现代设计模式。让我们深入了解其中的一些。
API 网关模式
将整个业务逻辑分解为多个微服务会带来各种问题,从而导致以下问题:
- 如何处理跨领域问题,如授权、速率限制、负载平衡、重试策略、服务发现等?
- 如何避免由于客户端到微服务之间的直接通信而导致的过多往返和紧密耦合?
- 如果客户端需要数据子集,谁将执行数据过滤和映射?
- 如果客户端需要调用多个微服务来获取数据,谁将进行数据聚合?
为了解决这些问题,API 网关位于客户端应用程序和微服务之间。它带来了反向代理、请求聚合、网关卸载、服务发现等功能。它可以为每个客户端公开不同的 API。
图 1:API 网关示例
客户端 UI 组合模式
在此模式中,微服务由面向业务能力的团队开发。某些 UI 屏幕可能需要来自多个微服务的数据。例如,购物网站将包括目录、购物车、购买选项、客户评论等功能。每个数据项都属于一个特定的微服务。现在,要显示的每个数据项都由不同的团队负责。我们该如何解决这个问题?
UI 团队应创建一个页面框架,该框架通过组合多个 UI 组件来构建屏幕。每个团队开发一个特定于服务的客户端 UI 组件。此框架也称为单页应用程序 (SPA)。像AngularJS指令和ReactJS组件这样的框架支持这一点。这也允许用户在任何数据更改时刷新屏幕的特定区域,从而提供更好的用户体验。
每个服务模式的数据库
微服务需要独立且松散耦合。那么微服务应用程序的数据库架构应该是什么呢?
- 典型的业务事务可能涉及来自不同团队拥有的多个服务的查询、联接或数据持久性操作。
- 在多语言微服务架构中,每个微服务可能有不同的数据存储要求,请考虑非结构化数据(NoSQL 数据库)、结构化数据(关系数据库)和/或图形数据 (Neo4j)。
- 数据库需要复制和分片才能进行扩展。
图 2:每个服务的数据库示例
微服务事务必须限制为其自己的数据库。任何其他需要该数据的服务都必须使用服务 API。如果使用关系数据库,则每个服务的架构是使数据专用于微服务的最佳选择。要创建障碍,请为每个服务分配不同的数据库用户 ID。这可确保开发人员不会试图绕过微服务的 API 并直接访问数据库。
这使每个微服务都能使用最适合其要求的数据库类型。例如,将 Neo4j 用于社交图数据,使用 Elasticsearch 进行文本搜索。
Saga 模式
当我们为每个服务使用一个数据库时,它会在实现跨多个微服务的事务时产生问题。在这种情况下,我们如何实现数据一致性?本地 ACID 事务在这里无济于事。解决方案是传奇模式。saga 是本地事务链,其中每个事务更新数据库并发布一个事件以触发下一个本地事务。saga 模式要求在任何本地事务失败时补偿事务。
有两种方法可以实现 saga:
- 业务流程 – 业务流程协调程序(对象)与所有服务协调,以执行本地事务、获取更新和执行下一个事件。如果发生故障,它有责任触发补偿事件。
- 编排 – 每个微服务负责侦听和发布事件,并在发生故障时启用补偿事件。
编排比编排更容易实现。在编排中,只有一个组件需要协调所有事件,而在编排中,每个微服务都必须侦听并响应事件。
断路器模式
在微服务体系结构中,事务涉及调用多个服务。如果下游微服务关闭,它将继续调用该服务,并耗尽所有其他服务的网络资源。它还会影响用户体验。我们如何处理级联故障?
电气断路器功能启发了断路器模式 — 这个问题的解决方案。代理位于客户端和微服务之间,用于跟踪连续失败的次数。如果超过阈值,它将触发连接并立即失败。超时期限后,断路器再次允许有限数量的测试请求来检查电路是否可以恢复。否则,超时期限将重置。
图 3:断路器级
Java的resilence4j框架提供了这种代理服务。
按业务能力或子域模式分解
在微服务架构中,大型复杂应用程序必须分解、内聚以及松散耦合。它也应该是自主的,足够小,可以由一个“披萨大小”的团队(六到八名成员)开发。我们如何分解它?
有两种方法可以分解绿地应用程序 — 按业务功能或子域:
- 业务能力是产生价值的东西。例如,在航空公司中,业务功能可以是预订、销售、付款、座位分配等。
- 子域概念来自域驱动设计 (DDD)。一个域由多个子域组成,例如产品目录、订单管理、交货管理等。
棕地应用的设计模式
由于我们构建应用程序已有数十年之久,因此大约 80% 的公司在称为棕地应用程序的现有应用程序上运行。将棕地应用程序迁移到微服务是最具挑战性的任务。让我们看一下某些有助于简化迁移的设计模式。
扼杀者无花果图案
如何将整体式应用程序迁移到微服务体系结构?扼杀者图案是基于藤蔓的类比,它扼杀了它所缠绕的树。在此模式中,整体式应用程序的一小部分将转换为微服务,对于客户而言,由于外部 API 保持不变,因此没有任何变化。慢慢地,所有部分都被重构为微服务,新的架构“扼杀”或取代了原来的单体架构。
防损层模式
当现代应用程序需要与旧版应用程序集成时,与过时的基础架构协议、API 和数据模型进行互操作具有挑战性。坚持旧的模式和语义可能会破坏新系统。我们怎样才能避免这种情况?
这需要一个层来转换两个系统之间的通信。防损层符合旧系统或现代系统的数据模型,具体取决于它与哪个系统通信以获取数据。它确保旧系统不需要更改,并且现代系统不会在其设计和技术上妥协。
图 4:防损层示例
结论
微服务架构为开发人员提供了很大的灵活性,但随着要管理的组件数量的增加,也带来了许多挑战。在本文中,我们讨论了构建和开发微服务应用程序所必需的最重要的设计模式。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· 分享4款.NET开源、免费、实用的商城系统
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· Windows 提权-UAC 绕过