你必须要了解的 10 种微服务设计模式!

360影视 2024-12-30 13:20 3

摘要:微服务是大型应用程序的一个小型、可独立部署的组件,专注于特定功能。每个微服务都运行自己的进程,通常通过 API 与其他服务进行通信,并且被设计为松散耦合,从而更容易扩展、开发和维护。

在详细介绍设计模式之前,我觉得有必要先重申下微服务的概念以及它带来的挑战。

微服务是大型应用程序的一个小型、可独立部署的组件,专注于特定功能。每个微服务都运行自己的进程,通常通过 API 与其他服务进行通信,并且被设计为松散耦合,从而更容易扩展、开发和维护。

与单体应用程序相比,微服务具有以下主要优势:

可扩展性:各个微服务可以根据需求独立扩展,优化资源使用。灵活性:可以使用不同的技术来开发、测试、部署和维护不同的微服务。更快的开发:规模较小、专注的团队可以同时处理单独的微服务,从而加快开发周期和发布时间。弹性:一个微服务中的故障被隔离,不太可能影响整个系统,从而提高整体可靠性。更容易维护:每个微服务的较小代码库更容易理解、修改和调试,从而减少技术债务。灵活外包:将业务功能外包给第三方合作伙伴时,知识产权保护可能是一个问题。微服务架构可以通过隔离合作伙伴特定的组件来提供帮助,确保核心服务保持安全且不受影响。

另一方面,它也面临着一些挑战:

复杂性:开发和维护基于微服务的应用程序通常比单一方法需要更多的努力。每个服务都需要自己的代码库、测试、部署管道和文档。服务间通信:微服务依赖于网络通信,这可能会在处理服务间通信时引入延迟、故障和复杂性。数据管理:分布式数据管理可能具有挑战性,因为每个微服务可能有自己的数据库,导致一致性、数据同步和事务等问题。部署开销:管理多个微服务的部署、版本控制和扩展可能需要复杂的编排和自动化工具,例如 Kubernetes。安全性:每个微服务都可能引入新的潜在漏洞,增加攻击面并需要仔细注意安全实践。

以下设计模式主要就是为了解决上述说的微服务面临的挑战(感觉翻成中文后不好理解了,还是直接放英文吧,大家可以结合后续的介绍来理解这些模式的含义)。这些模式大家在日常开发中或多或少都可能已经在用了,但不知道是这个设计模式:

Database Per Service PatternAPI Gateway PatternBackend For Frontend PatternCommand Query Responsibility Segregation (CQRS)Event Sourcing PatternSaga PatternSidecar PatternCircuit Breaker PatternAnti-Corruption LayerAggregator Pattern

Database Per Service Pattern 的核心理念是为每个微服务配备独立的专属数据库。这意味着,只有对应的微服务可以通过自身的 API 访问其数据库,其他微服务无法直接操作该数据库。

使用这种模式的主要优势

松耦合:微服务之间的依赖性减少,提升了系统的模块化程度。技术灵活性:团队可以根据各微服务的需求,选择最适合的数据库类型和配置,例如数据库种类或大小。

需要权衡的挑战

复杂性增加:维护多个数据库会带来更高的管理成本,包括备份、恢复、扩展等。跨服务查询困难:需要跨多个数据库查询时,通常需要借助 API Gateway Pattern 或 Aggregator Pattern 来实现。数据一致性问题:为了确保不同微服务数据库间的一致性,需要结合其他设计模式进行精心设计。

API Gateway 模式的核心在于通过一个统一的入口点(API 网关)处理所有客户端请求。API 网关在客户端与微服务之间充当中介,负责请求路由、响应聚合,并处理身份验证、负载均衡、日志记录和速率限制等横切问题。

使用 API 网关的主要优点

简化客户端交互:客户端只需与一个统一的 API 对接,而无需直接管理多个微服务的复杂性。集中管理:在网关中处理跨服务的通用功能(如身份验证或日志记录),减少了重复代码,提高了维护效率。增强安全性:通过网关强制实施安全策略和访问控制,有效保护底层微服务免受外部直接访问。

面临的主要挑战

单点故障风险:如果 API 网关出现问题,可能导致整个系统不可用。因此,需要确保网关的高可用性和弹性。性能瓶颈:未优化的网关可能成为系统的性能瓶颈,增加延迟,特别是在高并发场景下。

Backend For Frontend (BFF) 模式的核心思想是为每个特定的前端或客户端应用程序(如 Web 应用、移动应用、桌面应用)提供一个专属的后端服务。每个 BFF 针对其前端的具体需求设计,负责处理数据聚合、转换以及与底层微服务或 API 的交互。这个模式特别适合同时支持多个需求不同的前端应用的场景。

主要优势

优化前后端通信:BFF 精准响应前端的需求,减少不必要的数据传输,提高加载速度,带来更好的用户体验。简化前端开发:通过将复杂的业务逻辑、数据聚合和格式化放在 BFF 中,前端代码可以更专注于用户界面。独立演进:每个前端和对应的 BFF 可独立开发和迭代,提升了系统的灵活性和适应性。

主要挑战

复杂性增加:为每个前端维护单独的 BFF 需要额外的开发和运维成本。代码重复风险:如果通用功能未能抽象共享,可能导致多个 BFF 中出现重复代码。行为一致性:确保不同 BFF 之间的功能和逻辑一致性在大型系统中可能成为难题。

BFF 模式通过专用后端服务为前端提供量身定制的支持,但需要在设计和管理时平衡复杂性与灵活性,以避免潜在的维护负担。

CQRS(Command Query Responsibility Segregation)模式的核心思想是将数据的读取(查询)和写入(命令)职责分离到不同的模型或服务中。这种分离让每个模型可以专注于自己的功能,并进行针对性的优化。

模式核心:

命令模型(Command Model):专注于处理复杂的业务逻辑和状态变化,通常需要确保事务完整性。查询模型(Query Model):优化高效的数据检索和表示,通常采用非规范化视图或缓存以提升查询性能。

命令与查询模型之间的通信可以通过事件源、消息队列等技术来实现。

CQRS 模式的主要优点

性能优化:读写职责分离后,查询模型和命令模型可以根据不同需求独立优化,从而提升整体性能。可扩展性:读写操作能够单独扩展。例如,查询操作通常比写操作更频繁,可以为查询模型分配更多资源。维护性增强:分离职责后,代码库变得清晰,更易于理解、测试和修改。

面临的主要挑战

系统复杂性:需要单独管理和维护两个模型,并确保它们的正确通信和同步。数据一致性问题:在分布式环境下,命令和查询模型的数据可能存在延迟更新的问题,增加了设计复杂性。数据同步挑战:同步读取和写入模型,尤其是在数据量大或转换复杂的情况下,可能需要依赖事件源或消息队列等机制。

CQRS 模式适合复杂领域逻辑或高并发系统,虽然引入了额外的复杂性,但通过合理的设计和工具支持,可以有效提升系统的性能和可扩展性。

Event Sourcing Pattern(这个可以翻译成 “事件朔源模式“) 的核心是将系统中的状态变更以事件序列的形式记录下来,并存储在事件存储中,而不是直接保存当前状态。这些事件记录了每次状态变更的具体细节,允许通过重放事件来重建系统的当前状态。

模式核心:

事件存储:作为一个记录所有事件的存储系统,它类似消息代理,服务可以通过 API 订阅这些事件。事件重放:为了重建当前状态,事件存储中的事件会按顺序重放。如果事件量大,可利用快照优化,只需重放快照之后的事件。事件广播:当一个事件被记录后,会被推送给所有订阅者,实现事件驱动的交互。

主要优点

完整的审核跟踪:系统保留了所有状态变更的历史记录,便于审计、调试和了解系统的演变过程。高扩展性:仅存储事件的方式支持高效的写入操作,能够处理高并发和多消费者之间的大量写入请求。灵活的功能扩展:通过引入新的事件类型,可以轻松添加新功能,而无需修改现有逻辑。

面临的挑战

实现复杂性:与传统方法相比,管理事件流和重建状态需要更复杂的设计,并且团队需要时间掌握相关实践。存储空间消耗:因为所有事件都必须永久存储,用于追溯和重建,存储需求可能远高于传统方法。复杂的查询需求:直接查询事件数据通常较困难,必须依赖事件重建当前状态,可能导致性能问题。

Saga 模式是一种专为分布式系统设计的事务管理方式,用于协调跨多个微服务或数据库的长时间运行的业务事务。它将事务拆分为一系列本地事务,每个本地事务独立完成数据库更新并通过事件触发下一步操作。如果某一步失败,Saga 会执行补偿事务以撤销已完成的操作,从而保证数据的一致性。

下面是带有补偿事务的 saga 模式的说明示例:

img

Saga 模式的协调方式:

1)Choreography(协作式编排)

每个服务监听特定事件并触发下一步操作。无需中央控制,事件驱动的方式分散了服务间的压力,适合更去中心化的架构。示例:订单服务完成订单后发布事件,支付服务监听该事件并执行支付操作,支付完成后发布支付成功事件,触发后续物流服务。

2)Orchestration(集中式编排)

img

由一个中央编排器负责协调 Saga 的执行。编排器明确指示每个服务何时执行事务,并负责管理事务的整体流程。示例:一个专门的 Saga 管理器控制每个步骤的执行,确保从下单到支付再到发货按顺序完成。

虽然 "Choreography" 和 "Orchestration" 都可以翻译为“编排”,它们在实现方式上有显著差异:

Choreography 是对等模型,多个服务协作完成事务,强调去中心化。

Orchestration 是层次化模型,由中央服务负责协调,强调集中管理。

Saga 模式的主要优点

数据最终一致性:在分布式环境中,通过一系列事件和补偿操作,实现跨多个服务的数据一致性。弹性增强:将事务分解为小的独立步骤,结合补偿机制,使系统在发生故障时能够快速恢复并保持一致性。

面临的挑战

复杂性增加:补偿事务的设计和步骤的正确协调需要额外的开发工作,增加了系统实现和维护的难度。缺乏自动回滚:不像传统的 ACID 事务,Saga 模式没有内置的回滚机制,开发人员需要手动设计补偿逻辑以撤销已执行的操作。隔离性不足:Saga 不保证事务隔离,多个并发执行的 Saga 可能导致数据异常或冲突,需要额外的机制解决并发问题。

Saga 模式特别适合需要数据最终一致性、支持跨服务事务且容错能力强的分布式系统。通过在 Choreography 和 Orchestration 之间选择合适的方式,可以灵活满足不同场景的需求。然而,其实现复杂性和数据隔离问题需要在设计时重点考虑。

Sidecar 模式是一种将服务中的非核心功能分离到独立组件(称为 Sidecar 容器)的设计模式。这种模式允许核心服务专注于其主要职责,而 Sidecar 则负责处理辅助任务,如日志记录、监控或安全管理。通过这种解耦方式,增强了系统的模块化和可扩展性,同时避免了对核心服务代码的直接修改。

Sidecar 模式的典型用例

日志记录与监控:Sidecar 收集核心服务的日志或性能指标,并将其发送到集中式日志系统或监控工具。比如 一个 Sidecar 容器监控主服务的流量,并向 Prometheus 或 ELK 等系统推送数据。安全管理:Sidecar 负责身份验证、授权和加密等任务,从而简化主服务的安全实现。比如使用 Sidecar 执行 TLS 加密,为核心服务提供安全通信支持。

Sidecar 模式的主要优点

模块化和灵活性:通过将辅助功能封装到 Sidecar 容器中,开发人员可以轻松添加或移除功能,无需改动核心服务的代码。另外,这种设计促进了代码重用,提升了系统的可维护性。关注点分离:核心服务与 Sidecar 容器独立运行,隔离了辅助功能,降低了因 Sidecar 故障导致核心服务受影响的风险。独立扩展性:核心服务和 Sidecar 可以分别根据各自的需求进行扩展,提升资源利用率和系统弹性。

Sidecar 模式的主要缺点

增加系统复杂性:需要额外的容器部署和协调工作,增加了运维和管理的复杂度。比如 Kubernetes 环境中需要为每个 Pod 配置 Sidecar,增加了部署开销。潜在的单点故障:如果 Sidecar 容器失效,可能导致辅助功能不可用,需要冗余机制确保高可用性。性能开销:引入额外的通信路径,可能导致延迟上升,尤其在需要高实时性或高性能的场景中表现明显。同步和协调挑战:主服务与 Sidecar 之间需要保持严格同步,特别是在动态环境中,可能带来调试和配置上的困难。

总的来说,Sidecar 模式适用于微服务架构,尤其是在需要处理跨服务的通用功能时,如安全、日志或监控。尽管引入了额外的复杂性,但它通过解耦核心功能和辅助功能,提供了更大的灵活性和可扩展性。在设计时需仔细权衡其性能开销与管理难度,以确保满足系统需求。

断路器模式(Circuit Breaker Pattern)是一种增强分布式系统弹性与稳定性的设计模式。它通过监控服务调用的状态,在检测到连续故障后中断请求流,防止故障蔓延,确保系统能够优雅降级并快速恢复。

断路器的运行机制:

断路器通常有以下三种主要状态,每个状态对应服务调用的不同处理方式:

Closed(闭合):请求正常传递到服务,并监控响应状态。当检测到失败次数超过预设的阈值时,断路器会转为 Open(断开) 状态。Open(断开):阻止请求传递到服务,并直接返回错误或触发回退逻辑。此状态为服务提供恢复时间,避免进一步施加压力。Half-Open(半开):在预定义的恢复时间后,断路器允许少量测试请求通过以评估服务是否恢复。如果这些请求成功,断路器返回 Closed(闭合) 状态;否则回到 Open(断开) 状态。

断路器模式的优点

防止级联故障:当某服务不可用时,及时中断请求流,防止故障扩散至系统其他部分。增强系统弹性:通过隔离和控制故障,确保系统的其他部分能够持续运行,避免全局性崩溃。可靠性提升:在服务出现问题时,通过回退机制或错误响应,确保系统以可控方式对外提供服务,改善用户体验。

断路器模式的主要挑战:

阈值与恢复时间的配置:需要根据系统的特性与业务需求仔细调整阈值(如失败次数、时间窗口)和恢复时间,避免误判或延迟恢复。回退机制设计:系统需要有效的回退逻辑,以便在服务不可用时提供合理的替代响应。比如在搜索服务故障时,提供默认推荐或缓存数据,而不是返回完全的错误。复杂的监控与调试:分布式系统中,诊断断路器触发的原因或定位问题点可能较为复杂,特别是在系统调用链较长时。

使用场景

外部 API 调用:在调用第三方服务时,避免因其不可用而拖垮本地系统。微服务架构:隔离关键微服务故障对全局的影响,保障整体系统的稳定性。高并发系统:在流量高峰时,通过断路器避免部分服务过载。

ACL模式(反腐败层)旨在保护内部系统不受外部系统设计、协议和数据模型的影响。它通过在两个系统之间设置一层“屏障”,确保外部系统的复杂性或不一致性不会破坏内部系统的设计与稳定性。ACL 在系统架构中的作用类似于一个保护层,隔离了外部系统的变化对内部系统的影响。通过引入反腐败层,外部系统的变化不需要直接影响到内部系统的核心逻辑和数据模型。

ACL 内部的设计可以这样表示:

ACL 模式的主要优点

保护:保护内部系统免受外部更改和潜在损坏的影响。灵活性:通过管理数据模型和协议的差异,更轻松地与外部系统集成。可维护性:简化对内部或外部系统的修改和更新,而不影响另一个系统。

ACL 模式的主要缺点

延迟:两个系统之间的调用会增加延迟。扩展:使用许多微服务或整体应用程序扩展 ACL 可能是开发团队关心的问题。增加复杂性:由于需要翻译和适应逻辑,引入了额外的复杂性。

Aggregator Pattern(聚合器)核心是将多个源的数据或响应合并为一个统一的结果。Aggregator 组件或服务管理来自不同源的数据收集,协调获取、合并和处理数据的过程。

以下是聚合器模式的主要好处:

简化的客户端交互:客户端与一个服务或端点交互,降低了复杂性并提高了易用性。减少网络调用:将多个来源的数据聚合到一处,最大限度地减少客户端所需的调用或请求数量,并提高整体效率。集中数据处理:集中处理数据处理和转换,确保不同数据源之间的一致性和连贯性。

以下是这种模式的缺点:

增加复杂性:实现聚合逻辑可能很复杂,尤其是在处理不同的数据源和格式时。单点故障:由于聚合器充当数据收集的中心点,因此聚合器的任何问题或故障都可能影响整个系统的可用性或功能。延迟增加:聚合来自多个源的数据可能会带来额外的延迟,特别是当源是分布式的或者聚合涉及复杂的处理时。可扩展性挑战:扩展聚合器以处理不断增加的数据或请求量可能具有挑战性,需要仔细设计来管理负载并确保响应能力。

来源:小薇视讯n

相关推荐