10个微服务设计模式

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
云原生 API 网关,700元额度,多规格可选
EMR Serverless StarRocks,5000CU*H 48000GB*H
简介: 微服务设计模式是一种指导微服务架构设计和开发的一系列原则和实践。微服务设计模式的目的是为了解决微服务架构中遇到的一些常见的问题和挑战,比如服务划分、服务通信、服务治理、服务测试等。微服务设计模式可以帮助我们构建出高效、可靠、可扩展、可维护的微服务系统。

微服务设计模式是一种指导微服务架构设计和开发的一系列原则和实践。微服务设计模式的目的是为了解决微服务架构中遇到的一些常见的问题和挑战,比如服务划分、服务通信、服务治理、服务测试等。微服务设计模式可以帮助我们构建出高效、可靠、可扩展、可维护的微服务系统。

image.png

本文将介绍以下十种微服务设计模式:

  • API 网关(Api Gateway Pattern)
  • 服务发现与注册(Service Registration and Discovery Pattern)
  • 断路器(Circuit Breaker Pattern)
  • 隔板模式(Bulkhead Pattern)
  • 命令和查询职责分离(CQRS Pattern)
  • 事件驱动模式(Dvent Driven Pattern)
  • Saga 模式(Saga Pattern)
  • 扼杀者模式(Strangler Pattern)
  • 边车模式(Sidecar Pattern)
  • BFF 模式(Backend for Frontend Pattern)

1. API 网关

API 网关是访问任何微服务的入口点,位于客户端和微服务之间,负责处理诸如鉴权、限流、重试、负载均衡、服务发现等通用功能,以及根据客户端的需求进行数据过滤、映射和聚合等操作。这种模式可以简化客户端的逻辑,减少网络开销,保护后端服务,以及实现不同级别的 API 接口。在 Spring Cloud 中我们可以使用 Zuul 或 Spring Cloud Gateway 来实现这一点。

应用场景

  1. 对于任何微服务调用 API 网关是唯一入口,简化客户端逻辑。
  2. 可以根据不同的规则将请求路由到不同的微服务上。
  3. 可以与 Eureka、Nacos、Ribbon 等注册中心集成,实现服务发现和负载均衡。
  4. 可以聚合后端的请求结果再发送给前端。
  5. 可以在不同通信协议的服务之间做协议转换。
  6. 可以把授权/认证功能从微服务中迁移到 API 网关上。
  7. 可以记录请求日志。
  8. 可以做服务限流以及服务熔断。

2. 服务注册与发现

服务注册与发现是一种用于管理微服务实例地址变化的技术。它可以让微服务之间通过一个统一的服务名来进行通信,而不需要知道对方的具体位置。它主要包括两个组件:服务注册中心和服务发现客户端。

  • 服务注册中心:服务注册中心是一个中心化的组件,负责存储所有微服务实例的位置信息(如 IP 地址和端口号),以及提供查询和更新这些信息的接口。每个微服务实例在启动时都会向服务注册中心注册自己的位置信息,并定期发送心跳消息来维持自己的在线状态。如果某个微服务实例停止或下线了,它会从服务注册中心注销自己的位置信息,或者由服务注册中心检测到并删除它。
  • 服务发现客户端:服务发现客户端是一个分布式的组件,负责从服务注册中心获取所需微服务实例的位置信息,并根据负载均衡策略选择一个合适的实例进行调用。每个客户端或其他微服务在需要调用某个微服务时都会使用其服务名来请求服务发现客户端,由服务发现客户端返回一个可用的实例地址,并建立连接。

引入服务注册与发现可以给微服务架构带来很多好处,例如,

  • 动态发现:我们可以动态地发现新加入或退出的微服务实例,而不需要手动配置或修改地址信息。
  • 负载均衡:我们可以根据不同的算法(如轮询、随机、最少连接等)来选择最合适的微服务实例来处理请求,从而提高系统的性能和效率。
  • 容错处理:我们可以检测并排除不可用或故障的微服务实例,从而提高系统的可靠性和稳定性。

常见的服务注册中心如下,

  • Eureka:Eureka 是 Netflix 开源的一款服务发现组件,是 Spring Cloud 老版本的核心组件之一,现在已经处于维护期。它提供了服务注册、服务发现和负载均衡等功能,具有高可用、高可靠、易于扩展的特点。适用于需要高可用、易于部署和维护的微服务架构。
  • Consul:Consul 是由 HashiCorp 开源的一款服务网格解决方案,提供了服务注册、服务发现和健康检查等功能,同时还支持多数据中心部署和分布式一致性协议。适用于需要多数据中心部署和强一致性的微服务架构。
  • Zookeeper:Zookeeper 是 Apache 开源的一款分布式协调服务,提供了命名服务、配置管理、分布式锁等功能。Zookeeper 具有高可用、高可靠、支持集群和多数据中心等特点。适用于需要分布式锁、分布式配置管理等功能的微服务架构。
  • Nacos:Nacos 是阿里巴巴开源的一款动态服务发现、配置管理和服务管理平台,支持 DNS-based 和 RPC-based 两种模式。Nacos 具有简单易用、高性能、高可扩展等特点。适用于需要动态配置管理和服务治理的微服务架构。
  • Etcd:Etcd 是一个分布式键值存储系统,基于 Raft 协议实现了强一致性和容错性。Etcd 可以作为服务注册中心使用,也可以作为配置中心或分布式锁等其他场景使用。适用于需要强一致性和高性能的微服务架构。

3. 断路器

断路器是一种处理远程调用失败或超时的模式。由于微服务之间需要通过网络进行通信,因此可能会遇到网络故障、超时、拥塞等问题,导致远程调用失败或延迟。如果不及时处理这些问题,可能会造成雪崩效应(Cascading Failure),即一个失败的调用会引起其他调用的失败,最终导致整个系统崩溃。电路断路器模式可以避免这种情况,它类似于电路中的保险丝,当检测到某个远程调用出现故障时,就会切断该调用,防止进一步的损害,并尝试恢复该调用。在 Spring Cloud 中,我们可以使用 Hystrix 或 Resilient4J 来实现断路器。

断路器模式通常有三种状态:闭合(Closed)、打开(Open)和半开(Half-Open)。闭合状态表示远程调用正常工作,打开状态表示远程调用出现故障,半开状态表示远程调用正在恢复。电路断路器根据一定的条件和策略来切换这三种状态,比如故障次数、故障比例、故障时间等。电路断路器还可以提供一些备选方案来处理失败的调用,比如重试、降级、缓存等。

断路器行为类似于电路中的断路器。当连续的请求失败的次数超过阈值时,断路器将跳闸一段时间,并且在跳闸的这段时间内,所有远程服务调用的尝试都将立即失败。当超过了断路器跳闸时间之后,断路器将允许有限数量的测试请求通过。如果这些请求成功,则断路器将恢复正常操作。否则如果有一个请求失败,则断路器再次跳闸。对于一个应用试图尝试调用另一个远程服务或者获取共享资源,并且该操作很容易的失败的情况来说, 这个模式非常适用。

3. 隔板模式

隔板模式(Bulkhead Pattern)通过根据需要调用的服务数量划分线程池,帮助处理与线程池相关的容错问题。例如我们在服务 A 中定义了一个 50 线程池,服务 A 会向服务 B 和 C 发出请求。因此服务 A 应该将 50 线程池分为 2 个(服务 B 25 个,服务 C 25 个),如果服务 C 不可用或需要较长时间来处理请求,则不会影响服务 B 调用,因为它有自己的线程池来执行作业。在 Spring Cloud 中,我们可以使用 Resilient4J 来实现这一点。

隔板模式类似于船体中一个个被隔离的分区。根据使用者负载和可用性要求,这些分区服务实例被分割到不同的组里面。这种设计模式有助于隔离故障(isolate failures), 并允许即使在故障期间仍可为某些使用者提供服务功能。

5. 命令和查询职责分离

命令和查询职责分离(Command Query Responsibility Segregation,CQRS)模式,是一种将数据存储的读取操作和更新操作分离的模式。这种模式的目的是提高微服务的性能、可扩展性和安全性。CQRS 的基本思想是,对于不同的操作,可以使用不同的模型、服务和数据库。例如,读取操作可以使用一个优化了查询效率的数据库,而更新操作可以使用一个保证了数据一致性的数据库。这样就可以根据不同的需求来选择合适的技术和架构。

优点

  • 可以根据读写比例来调整资源分配,提高系统的效率和响应速度。
  • 可以针对不同的场景使用不同的数据模型和验证规则,提高系统的灵活性和可维护性。
  • 可以降低数据冲突和并发问题的风险,提高系统的可靠性和安全性。

缺点

  • 需要维护多个数据源之间的同步和一致性,增加了系统的复杂度和开发成本。
  • 需要处理数据延迟和最终一致性的问题,可能影响用户体验和业务逻辑。

6. 事件驱动模式

微服务中的事件驱动模式是一种让微服务之间通过发布和订阅事件来进行异步通信的模式。事件是一种表示系统中发生了某种变化或动作的消息,比如订单创建、支付完成、用户注册等。事件驱动模式的优点是可以降低微服务之间的耦合度,提高系统的可扩展性、性能和可靠性,以及支持复杂的业务逻辑和流程。事件驱动模式的挑战是需要保证事件的顺序、一致性、幂等性和可追溯性,以及处理分布式事务和异常情况。事件驱动模式中的事件一般是通过消息队列发出,例如 RabbitMQ 或 Apache Kafka。

事件驱动模式让微服务之间通过发布和订阅事件来进行异步通信,而不是直接调用或依赖其他微服务的接口。这样每个微服务只需要关注自己的业务逻辑,而不需要知道其他微服务的存在和状态。

7. Saga 模式

众所周知,处理分布式系统很困难,尤其是涉及分布式事务时,二阶段提交是最好的选择,但由于其悲观锁的性质使其难以扩展、性能较低,所以就有了 Saga 模式,是一种在分布式事务场景中跨微服务管理数据一致性的方法。Saga 是一系列事务,用于更新每项服务并发布消息或事件来触发下一个事务步骤。如果某个步骤失败,则 Saga 将执行补偿事务,以抵消上一个事务的影响。这种模式可以保证数据的最终一致性,同时避免了长时间锁定资源的问题。有两种常见的 Saga 实现方法,即协调和编排。 每个方法都有自己的一组挑战和技术来协调工作流。

协调

协调是协调 Saga 的一种方法,参与者在没有集中控制点的情况下交换事件。 通过协调,每个本地事务都会发布在其他服务中触发本地事务的域事件。。

image.png

好处

  • 适用于只需很少参与者且不需要协调逻辑的简单工作流。
  • 不需要额外的服务实现和维护。
  • 不会引入单一故障点,因为责任在各个 Saga 参与者之间进行分配。

缺点

  • 添加新步骤时,工作流可能会变得混乱,因为很难跟踪哪些 Saga 参与者侦听哪些命令。
  • 由于 Saga 参与者必须使用彼此的命令,因此他们之间存在循环依赖的风险。
  • 集成测试很困难,因为必须运行所有服务才能模拟事务。

编排

编排是协调 Saga 的一种方法,在此方法中,中央控制器告诉 Saga 参与者要执行的本地事务。 Saga 编排器处理所有事务,并告知参与者根据事件执行哪项操作。 编排器执行 Saga 请求、存储和解释每个任务的状态,并通过补偿事务处理故障恢复。

image.png

好处

  • 适用于只需很少参与者且不需要协调逻辑的简单工作流。
  • 不需要额外的服务实现和维护。
  • 不会引入单一故障点,因为责任在各个 Saga 参与者之间进行分配。

缺点

  • 添加新步骤时,工作流可能会变得混乱,因为很难跟踪哪些 Saga 参与者侦听哪些命令。
  • 由于 Saga 参与者必须使用彼此的命令,因此他们之间存在循环依赖的风险。
  • 集成测试很困难,因为必须运行所有服务才能模拟事务。

8. 扼杀者模式

扼杀者(Strangler Pattern)模式是一种将单体应用逐渐迁移到微服务架构的模式,它的灵感来源于一种缠绕并杀死它所依附的树木的藤蔓植物。扼杀者模式的基本思想是,通过创建单体应用的新版本来替换旧版本,同时保持外部 API 不变,让客户端感知不到任何变化。随着转换进度的推进,最终所有功能都被重构为微服务,新架构“扼杀”取代了原来的单体架构。

扼杀应用(Strangler Application)的步骤分为转换,共存和消灭三步:

  • 转换(Transform ) —  用新方式创建一个新的平行的服务。
  • 共存(Coexist )—  保持老服务,将老服务请求重定向到新服务,新服务逐步实现老服务的功能。
  • 消灭(Eliminate ) —  移除老服务。

扼杀者模式的优点是可以渐进地进行微服务化,而不是一次性地重写整个应用,这样可以降低风险和成本,同时保持业务的连续性和稳定性。缺点是需要维护两套系统之间的兼容性和同步性,这可能会增加系统的复杂度和开发成本。

9. 边车模式

边车模式(Sidecar Pattern)是一种将一些与业务逻辑无关的功能(如日志、监控、配置、安全等)从主应用程序中分离出来,部署在同一个主机或容器中的一个独立的进程或服务中的模式。这样,主应用程序可以专注于自己的核心功能,而边车服务可以提供一些通用的功能,比如数据转换、网络通信、故障处理等。边车服务与主应用程序之间通过本地接口或共享内存来进行通信,从而实现高效和透明的协作。

边车模式的优点是可以降低微服务之间的耦合度,提高微服务的性能、可靠性和灵活性,以及简化微服务的开发和维护。缺点是需要额外的资源和管理成本,以及处理边车与主应用程序之间的通信和协调问题。

10. BFF 模式

BFF 模式是一种为前端定制的后端的模式,它的全称是 Backend for Frontend。BFF 模式的目的是将后端的微服务根据不同的前端渠道和场景进行适配和聚合,提供给前端友好和统一的 API,从而提升前端的用户体验和开发效率。BFF 模式可以让前端与后端之间实现更好地解耦和协作。

BFF 模式的优点是可以根据不同的前端需求来定制和优化 API,避免了过度抽象或者冗余的 API,提高了网络传输和数据处理的效率。缺点是需要额外的开发和维护成本,每个前端渠道都需要一个对应的 BFF,可能会导致代码重复或者不一致。

应用场景

  1. 接口剪裁:后端提供的一个接口,对于不同的前端场景来说,需求的字段可能会不同。BFF 的剪裁能力使得后端只需要专注领域开发,不需要为前端定制不同的 API 接口,方便 API 生命周期的管理。
  2. 接口聚合:一个前端页面,往往会依赖多个后端接口,这样就需要和后端产生多次交互。BFF 可以对后端接口进行聚合,并处理依赖关系,使得前端一个页面只需要和后端交互一次。

总结

以上的十种设计模式能帮助我们构建扩展性良好的软件系统,但是在生产实践中,我们还需要根据具体的业务场景和需求来引入合适的微服务设计模式。

最后感谢大家阅读,希望本文能对你有所帮助.

目录
相关文章
|
23天前
|
设计模式 API 持续交付
深入理解微服务架构:设计模式与实践
【10月更文挑战第19天】介绍了微服务架构的核心概念、设计模式及最佳实践。文章详细探讨了微服务的独立性、轻量级通信和业务能力,并介绍了聚合器、链式和发布/订阅等设计模式。同时,文章还分享了实施微服务的最佳实践,如定义清晰的服务边界、使用API网关和服务发现机制,以及面临的挑战和职业心得。
|
6月前
|
设计模式 Java API
【设计模式】JAVA Design Patterns——Aggregator Microservices(聚合器微服务模式)
【设计模式】JAVA Design Patterns——Aggregator Microservices(聚合器微服务模式)
|
4月前
|
设计模式 存储 运维
微服务架构中的服务发现与注册中心设计模式
在现代软件工程实践中,微服务架构已成为构建灵活、可扩展系统的首选方案。本文将深入探讨微服务架构中至关重要的服务发现与注册中心设计模式。我们将从服务发现的基本原理出发,逐步解析注册中心的工作机制,并以Eureka和Consul为例,对比分析不同实现的优劣。文章旨在为开发者提供一套清晰的指导原则,帮助他们在构建和维护微服务系统时做出更明智的技术选择。
|
4月前
|
设计模式 监控 Java
探索微服务架构的弹性设计模式
【7月更文挑战第19天】在现代后端开发中,微服务架构因其灵活性、可扩展性而受到企业的青睐。本文将深入探讨微服务架构中的弹性设计模式,包括其定义、重要性以及如何通过技术手段实现服务的高可用性和容错性。我们将通过实例分析,展示如何在微服务系统中应用这些模式以提高系统的整体稳定性和响应能力。
59 1
|
5月前
|
设计模式 负载均衡 安全
探索微服务架构下的API网关设计模式
【6月更文挑战第14天】本文将深入探讨在微服务架构中,API网关的设计模式及其对系统性能和安全性的影响。通过分析不同的设计模式,我们将了解如何在保障服务高可用性和可扩展性的同时,确保系统的灵活性和响应速度。
|
6月前
|
设计模式 Java 关系型数据库
BAT等大厂年薪30W+面试清单:JVM\MySQL\设计模式\分布式\微服务
疫情影响下招聘名额缩减不少,但阿里、腾讯、抖音、快手等互联网公司却加快了人才招聘的节奏。这里根据自身的实际经历,整理了一份面试这些大厂的清单,希望能帮助到大家查漏补缺,攻克面试难关。
|
设计模式 存储 API
微服务架构及设计模式
逛github时看到了一篇很好的文章,转载过来分享给大家,版权归原作者所有,侵删,原文地址为:https://colstuwjx.github.io/2020/01/%E7%BF%BB%E8%AF%91-%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%9E%B6%E6%9E%84%E5%8F%8A%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/
java初中级面试题(SSM+Mysql+微服务(SpringCloud+Dubbo)+消息队列(RocketMQ)+缓存(Redis+MongoDB)+设计模式+搜索引擎(ES)+JVM
java初中级面试题(SSM+Mysql+微服务(SpringCloud+Dubbo)+消息队列(RocketMQ)+缓存(Redis+MongoDB)+设计模式+搜索引擎(ES)+JVM
520 0
java初中级面试题(SSM+Mysql+微服务(SpringCloud+Dubbo)+消息队列(RocketMQ)+缓存(Redis+MongoDB)+设计模式+搜索引擎(ES)+JVM
java初中级面试题(SSM+Mysql+微服务(SpringCloud+Dubbo)+消息队列(RocketMQ)+缓存(Redis+MongoDB)+设计模式+搜索引擎(ES)+JVM
661 0
java初中级面试题(SSM+Mysql+微服务(SpringCloud+Dubbo)+消息队列(RocketMQ)+缓存(Redis+MongoDB)+设计模式+搜索引擎(ES)+JVM
java初中级面试题(SSM+Mysql+微服务(SpringCloud+Dubbo)+消息队列(RocketMQ)+缓存(Redis+MongoDB)+设计模式+搜索引擎(ES)+JVM
800 0