<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path> </svg>
讯享网
原文链接:https://dzone.com/articles/design-patterns-for-microservices
了解微服务软件架构的设计模式,以克服松散耦合服务、定义数据库等挑战。
经过
微服务架构已成为现代应用程序开发的事实选择。虽然它解决了许多问题,但它并不是灵丹妙药。与所有软件一样,它也有自己独特的挑战需要解决。这就需要学习微服务中的常见设计模式,并使用可重用的解决方案来解决上述挑战。
在深入研究设计模式之前,了解微服务架构的核心原则非常重要:
图 1*:微服务架构核心实践*
应用这些原则通常会带来一些挑战和问题。在本文中,我们将详细介绍关键的微服务模式、它们解决的常见问题以及它们提供的解决方案。
掌握微服务架构 | 立即报名参加免费在线课程*
*附属链接。请参阅 使用条款。
本指南可作为关键微服务模式和系统设计策略的参考,以有效构建您的微服务架构。让我们开始吧。
模式一:按业务能力分解
问题
微服务就是使服务松散耦合,从而应用单一责任原则。但是,将应用程序分解为更小的部分必须合乎逻辑。我们如何将应用程序分解为小服务?
解决方案
一种策略是按业务能力进行分解。业务能力是企业为创造价值而做的事情。给定业务的能力集取决于业务类型。例如,保险公司的能力通常包括销售、营销、承保、索赔处理、计费、合规等。每项业务能力都可以被视为一项服务——只不过它是面向业务的,而不是面向技术的。
模式2:按子域分解
问题
使用业务功能分解应用程序可能是一个好的开始,但您会遇到所谓的“上帝类”,这些类不容易分解。这些类将在多个服务中很常见。例如,该类将用于订单管理、订单处理、订单交付等。我们如何分解它们?
解决方案
对于“上帝类”问题,DDD(领域驱动设计)可以提供帮助。它使用子域和有界上下文概念来解决这个问题。DDD 将为企业创建的整个领域模型分解为子域。每个子域都有一个模型,该模型的范围称为有界上下文。每个微服务都将围绕有界上下文进行开发。
注意:识别子域并非易事。它需要了解业务。与业务能力一样,子域是通过分析业务及其组织结构并确定不同的专业领域来识别的。
模式 #3:绞杀者模式
问题
到目前为止,我们讨论的设计模式都是针对绿地应用程序进行分解,但我们所做的 80% 的工作都是针对棕地应用程序,即大型单片应用程序。将上述所有设计模式应用于它们将很困难——在使用的同时将它们分解成较小的部分是一项艰巨的任务。
解决方案
绞杀者模式可以解决这个问题。绞杀者模式基于一种类比,即藤蔓会绞死缠绕在其上的一棵树。此解决方案适用于来回调用的 Web 应用程序,对于每个 URI 调用,服务可以拆分为不同的域并托管为单独的服务。其理念是一次在一个域中执行此操作。这会创建两个并存于同一 URI 空间中的独立应用程序。最终,新重构的应用程序会“绞杀”或替换原始应用程序,直到最后您可以关闭整体式应用程序。
模式4:API网关模式
问题
当应用程序分解为更小的微服务时,需要解决一些问题:
- 如何调用多个微服务抽象生产者信息。
- 在不同的渠道(如桌面、移动设备和平板电脑)上,应用程序需要不同的数据来响应相同的后端服务,因为 UI 可能不同。
- 不同的消费者可能需要可重用微服务的响应格式不同。谁来做数据转换或字段操作?
- 如何处理不同类型的协议——其中一些可能不受生产者微服务支持。
解决方案
API 网关有助于解决微服务实现所引发的许多问题,不仅限于上述问题:
- API 网关是任何微服务调用的单一入口点。
- 它可以作为代理服务,将请求路由到相关的微服务,抽象生产者的详细信息。
- 它可以将请求分发给多个服务,并汇总结果发送回给消费者。
- 一刀切的 API 无法解决所有消费者的需求;此解决方案可以为每种特定类型的客户端创建细粒度的 API。
- 它还可以将协议请求(例如 AMQP)转换为另一种协议(例如 HTTP)或反之亦然,以便生产者和消费者可以处理它。
- 它还可以减轻微服务的身份验证/授权责任。
模式 #5:聚合器模式
问题
如上所述,我们在解决 API 网关模式中的聚合数据问题时面临挑战。将业务功能分解为几个较小的逻辑代码片段时,有必要考虑如何协作每个服务返回的数据。这个责任不能留给消费者,因为它可能需要了解生产者应用程序的内部实现。
解决方案
聚合器模式有助于解决这个问题。它讨论了如何聚合来自不同服务的数据,然后将最终响应发送给消费者。这可以通过两种方式完成:

- 复合微服务将调用所有必需的微服务,合并数据,并在发送回之前转换数据。
- API网关还可以将请求划分为多个微服务,并在发送给消费者之前聚合数据。
如果要应用任何业务逻辑,建议选择复合微服务。否则,API 网关是既定的解决方案。
模式 #6:客户端 UI 组合
问题
当通过分解业务功能/子域来开发服务时,负责用户体验的服务必须从多个微服务中提取数据。在单片架构中,过去从 UI 到后端服务只有一个调用来检索所有数据并刷新/提交 UI 页面。但是,现在情况不一样了,所以我们需要了解如何做到这一点。
解决方案
对于微服务,UI 必须设计为具有屏幕/页面的多个部分/区域的骨架。每个部分将调用单个后端微服务来提取数据。这称为组合特定于服务的 UI 组件。AngularJS 和 ReactJS 等框架可帮助您轻松完成此操作。这些屏幕称为单页应用程序 (SPA)。这使应用程序能够刷新屏幕的特定区域,而不是整个页面。
模式 7:每个服务都有数据库
问题
团队经常面临如何为微服务定义数据库架构的挑战。以下是必须解决的问题:
- 服务必须是松散耦合的。它们可以独立开发、部署和扩展。
- 业务交易可能会强制执行跨多个服务的不变量。
- 一些业务事务需要查询多个服务拥有的数据。
- 有时为了扩展,数据库必须被复制和分片。
- 不同的服务有不同的数据存储要求。
解决方案
为了解决上述问题,必须为每个微服务设计一个数据库。该数据库必须仅对该服务专用,并且只能通过微服务 API 访问。其他服务不能直接访问它。
例如,对于关系数据库,我们可以使用每个服务一个私有表、每个服务一个模式或每个服务一个数据库服务器。每个微服务都应该有一个单独的数据库 ID,以便可以给予单独的访问权限,以设置屏障并防止其使用其他服务表。

图 2:每个服务架构一个数据库
模式 8:每个服务共享数据库
问题
我们讨论过,对于微服务来说,每个服务一个数据库是理想的选择,但这只有在应用程序是全新且使用 DDD 开发时才有可能。如果应用程序是一个整体式应用程序,并试图将其拆分为微服务,那么非规范化就不那么容易了。那么在这种情况下,最合适的架构是什么?
解决方案
每个服务共享一个数据库并不理想,但这是上述场景的有效解决方案。大多数人认为这是微服务的反模式,但对于棕地应用程序来说,这是将应用程序分解为更小的逻辑部分的良好起点。
在这种模式下,一个数据库可以与多个微服务对齐,但最多只能限制为 2-3 个;否则,扩展、自主和独立性将难以执行:

图 3:共享数据库架构
模式#9:命令查询责任分离(CQRS)
问题
一旦我们实现了每个服务一个数据库,就需要查询,这需要来自多个服务的联合数据——这是不可能的。那么,我们如何在微服务架构中实现查询?
解决方案
CQRS 建议将应用程序分为两部分 -命令端和查询端。命令端处理、和请求。查询端使用物化视图处理查询组件。事件源设计模式通常与其一起使用,以创建任何数据更改的事件。因此,通过订阅事件流,物化视图可以保持最新状态。
模式#10:Saga模式
问题
当每个服务都有自己的数据库,并且业务事务跨越多个服务时,我们如何确保跨服务的数据一致性?例如,对于客户有信用额度的电子商务应用程序,应用程序必须确保新订单不会超出客户的信用额度。由于订单和客户位于不同的数据库中,因此应用程序不能简单地使用本地 ACID 事务。
解决方案
Saga 代表由多个子请求组成的高级业务流程,每个子请求都会更新单个服务中的数据。每个请求都有一个补偿请求,当请求失败时执行该请求。它可以通过两种方式实现:
- 编排——当没有中央协调时,每个服务都会生成并监听另一个服务的事件,并决定是否应该采取行动。
- 编排——编排器(对象)负责传奇的决策和排序业务逻辑。
接下来,让我们深入探讨可观察性的微服务模式。下面,我们有一个示例微服务架构图,供所有可观察性主题参考。

图 4*:微服务可观察性* 图(来源: CNCF)

模式11:日志聚合
问题
考虑这样一个用例:一个应用程序由多个服务实例组成,这些服务实例在多台机器上运行。请求通常跨越多个服务实例。每个服务实例都会生成一个标准化格式的日志文件。我们如何通过特定请求的日志了解应用程序的行为?
解决方案
我们需要一个集中式日志记录服务,用于汇总来自每个服务实例的日志。用户可以搜索和分析日志。他们可以配置当日志中出现某些消息时触发的警报。例如,PCF 确实有 Loggeregator,它可以收集来自 PCF 平台的每个组件(路由器、控制器、diego 等)以及应用程序的日志。AWS Cloud Watch 也做同样的事情。
模式 #12:绩效指标
问题
当服务组合由于微服务架构而增加时,密切关注交易变得至关重要,这样才能监控模式并在发生问题时发送警报。我们应该如何收集指标来监控应用程序性能?
解决方案
需要指标服务来收集有关单个操作的统计信息。它应该聚合应用程序服务的指标,从而提供报告和警报。聚合指标有两种模型:
- 推送 ——该服务将指标推送到指标服务,例如 New Relic、AppDynamics 等。
- 拉取——指标服务从服务(例如 Prometheus)中提取指标。
模式#13:分布式跟踪
问题
在微服务架构中,请求通常跨越多个服务。每个服务通过跨多个服务执行一个或多个操作来处理请求。那么,我们如何端到端跟踪请求以解决问题呢?
解决方案
我们需要这样的服务:
- 为每个外部请求分配一个唯一的外部请求 ID。
- 将外部请求ID传递给所有服务。
- 在所有日志消息中包含外部请求 ID。
- 记录有关在集中服务中处理外部请求时执行的请求和操作的信息(例如开始时间、结束时间等)。
Spring Cloud Slueth 与 Zipkin 服务器一起是一种常见的示例实现。
模式#14:健康检查
问题
当实施微服务架构时,可能会出现服务已启动但无法处理事务的情况。在这种情况下,如何确保请求不会发送到这些失败的实例?我们可以通过负载平衡模式实施来解决这个问题。
解决方案
每个服务都需要有一个端点,可用于检查应用程序的健康状况,例如。此 API 应检查主机的状态、与其他服务/基础设施的连接以及任何特定逻辑。
Spring Boot Actuator 确实实现了一个 端点,并且可以定制该实现。
模式#15:外部化配置
问题
服务通常还会调用其他服务和数据库。对于每个环境(如开发、QA、UAT 和/或生产),端点 URL 或其他配置属性可能会有所不同。任何这些属性的更改都可能需要重新构建和重新部署服务。我们如何避免因配置更改而修改代码?
解决方案
外部化配置(包括端点 URL 和凭证)将缓解此问题。应用程序应在启动时或运行过程中加载它们。
Spring Cloud 配置服务器提供了将属性外部化到 GitHub 并将其加载为环境属性的选项。应用程序可以在启动时访问这些属性,也可以在不重启服务器的情况下刷新这些属性。
模式#16:服务发现
问题
当微服务出现时,我们需要解决调用服务方面的一些问题:
- 使用容器技术,IP 地址会动态分配给服务实例。每次地址更改时,消费者服务都可能中断并需要手动更改。
- 每个服务URL都必须被消费者记住,并且紧密耦合。
那么消费者或路由器如何知道所有可用的服务实例和位置?
解决方案
需要创建一个服务注册表,它将记录每个生产者服务的元数据。服务实例应在启动时注册到注册表,并在关闭时取消注册。因此,消费者或路由器应查询注册表并找出服务的位置。
注册中心还需要对生产者服务进行健康检查,以确保只有服务的工作实例可用并能够通过它使用。服务发现有两种类型:客户端和服务器端。客户端发现的一个示例是Netflix Eureka,服务器端发现的一个示例是AWS ALB。
模式#17:断路器
问题
服务通常会调用其他服务来检索数据,下游服务可能会出现故障。这会带来两个问题:首先,请求会不断发送到故障服务,从而耗尽网络资源并降低性能。其次,用户体验会很差且不可预测。我们如何避免级联服务故障并妥善处理故障?
解决方案
消费者应通过代理来调用远程服务,该代理的行为方式类似于电气断路器。当连续故障次数超过阈值时,断路器将跳闸,在超时期限内,所有调用远程服务的尝试都将立即失败。超时到期后,断路器将允许有限数量的测试请求通过。如果这些请求成功,断路器将恢复正常运行。否则,如果发生故障,超时期限将重新开始。
Netflix Hystrix是断路器模式的一个很好的实现。它还有助于定义回退机制,当断路器跳闸时可以使用该机制。这提供了更好的用户体验。
模式#18:蓝绿部署
问题
在微服务架构中,一个应用程序可以拥有多个微服务。如果我们停止所有服务,然后部署增强版本,停机时间可能会很长,并影响业务。此外,任何回滚都将是一场噩梦。那么我们如何避免或减少部署期间服务的停机时间?
解决方案
可以实施蓝绿部署策略来减少或消除停机时间。它通过运行两个相同的生产环境(蓝色和绿色)来实现这一点。假设绿色是现有的实时实例,蓝色是应用程序的新版本。在任何时候,只有一个环境是实时的,实时环境为所有生产流量提供服务。所有云平台都提供了实施蓝绿部署的选项。
还有其他几种关键的微服务架构模式,例如 sidecar 模式、链式微服务、分支微服务、事件源设计模式、大使模式等等。随着微服务的发展,这个列表还在不断增加,因此我们很乐意在下面的评论中听取您关于您正在使用的微服务模式的意见!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/183390.html