微服务可以对您的企业产生积极影响。因此,有必要了解如何处理微服务架构(MSA)和一些微服务设计模式,以及微服务架构的一般目标或原则。以下是微服务架构方法中需要考虑的四个目标 [1]。
降低成本: MSA 将降低设计、实施和维护 IT 服务的总体成本。
提高发布速度: MSA 将提高服务从构思到部署的速度。
提高弹性: MSA 将提高我们服务网络的弹性。
启用可见性: MSA 支持提高您的服务和网络的可见性。
你需要了解微服务架构构建的原则是什么
可扩展性
可用性
弹性
灵活性
独立、自治
去中心化治理
故障隔离
自动配置
通过 DevOps 持续交付
在实施您的解决方案或系统时,遵守上述原则会带来一些挑战和问题。这些问题对于许多解决方案来说都很常见。这些可以通过使用正确且匹配的设计模式来克服。微服务有多种设计模式,可分为五种模式。每个都包含许多模式。
分解模式
按业务能力进行分解微服务就是使服务松散耦合并应用单一责任原则。它按业务能力分解。定义与业务能力对应的服务。业务能力是业务架构建模中的一个概念[2]。这是企业为了创造价值而做的事情。一个业务能力往往对应一个业务对象,例如
订单管理负责订单
客户管理对客户负责
按子域分解
使用业务功能分解应用程序可能是一个好的开始,但是您会遇到所谓的“上帝类”,它们不容易分解。这些类在多种服务中是通用的。定义与领域驱动设计 (DDD) 子域相对应的服务。DDD 将应用程序的问题空间(业务)称为域。一个域由多个子域组成。每个子域对应于业务的不同部分。子域可以分类如下:
核心 ——业务的关键差异化因素和应用程序最有价值的部分
支持 ——与业务相关,但不是差异化因素;可以在内部或外包实施
通用 ——不特定于业务,最好使用现成的软件来实现
订单管理的子域包括:
产品目录服务
库存管理服务
订单管理服务
交付管理服务
按事务分解/两阶段提交 (2pc) 模式
这种模式可以分解事务上的服务。那么系统中就会出现多笔交易。分布式事务的重要参与者之一是事务协调器[3]。分布式事务包括两个步骤:
准备阶段 ——在此阶段,事务的所有参与者准备提交并通知协调者他们已准备好完成事务
提交或回滚阶段 ——在此阶段,事务协调器向所有参与者发出提交或回滚命令
2PC 的问题是,与单个微服务的运行时间相比,它相当慢。协调微服务之间的事务,即使它们位于同一网络上,也会确实降低系统速度;所以这种方法通常不用于高负载场景。
绞杀者图案
您经历的前三种设计模式是分解 Greenfield 应用程序,但您所做的 80% 的工作是处理 Brownfield 应用程序,这些应用程序是大型的整体应用程序(遗留代码库)。Strangler 模式可以解决问题。这将创建两个独立的应用程序,它们并排存在于同一 URI 空间中。随着时间的推移,新重构的应用程序会“扼杀”或取代原始应用程序,直到最后,您可以关闭单体应用程序。Strangler 应用步骤进行改造、共存、消除[4]:
转型 ——用现代方法创建一个并行的新站点。
共存 — 将现有站点暂时保留在原处。从现有站点重定向到新站点,以便逐步实现该功能。
消除 — 从现有站点中删除旧功能。
舱壁图案
这种模式将应用程序的元素隔离到池中,这样,如果其中一个失败,其他元素将继续运行。这种图案被称为舱壁,因为它类似于船体的分段隔板。根据消费者负载和可用性要求,将服务实例划分为不同的组。此设计有助于隔离故障,并允许您即使在故障期间也能维持某些使用者的服务功能。
边车模式
这会将应用程序的组件部署到单独的处理器容器中以提供隔离和封装。此模式还可以使应用程序由异构组件和技术组成。这种图案被命名为“Sidecar”,因为它类似于附加在摩托车上的“Sidecar”。在该模式中,边车附加到父应用程序并为应用程序提供支持功能。sidecar 还与父应用程序共享相同的生命周期,与父应用程序一起创建和退出。sidecar 模式有时称为 sidekick 模式,是我们在帖子中展示的最后一个分解模式。
集成模式
API 网关模式 当应用程序分解为更小的微服务时,需要解决一些问题
不同渠道对多个微服务有多次调用。
需要处理不同类型的协议。
不同的消费者可能需要不同格式的响应。
API 网关有助于解决微服务实现带来的许多问题,而不仅限于上述问题。
API 网关是任何微服务调用的单一入口点。
它可以作为代理服务将请求路由到相关的微服务。
它可以聚合结果并发回给消费者。
该解决方案可以为每种特定类型的客户端创建细粒度的 API。
它还可以转换协议请求和响应。
它还可以减轻微服务的身份验证/授权责任。
聚合器模式
当将业务功能分解为几个较小的逻辑代码片段时,有必要考虑如何协作每个服务返回的数据。这个责任不能留给消费者。
聚合器模式有助于解决这个问题。它讨论了我们如何聚合来自不同服务的数据,然后将最终响应发送给消费者。这可以通过两种方式完成[6]:
组合微服务将调用所有必需的微服务、整合数据并在发送回之前转换数据。
API 网关还可以将请求划分为多个微服务,并在将数据发送给消费者之前聚合数据。
如果要应用任何业务逻辑,建议选择组合微服务。否则,API Gateway 就是既定的解决方案。代理模式 API 网关只是通过 API 网关公开微服务。在本例中,API网关具有三个API模块:
Mobile API,实现FTGO移动客户端的API。
浏览器 API,它为浏览器中运行的 JavaScript 应用程序实现 API。
公共API,为第三方开发者实现API。
网关路由模式
API网关负责请求路由。API网关通过将请求路由到相应的服务来实现一些API操作。当 API 网关收到请求时,它会查阅路由映射,该映射指定将请求路由到哪个服务。例如,路由映射可以将 HTTP 方法和路径映射到服务的 HTTP URL。此功能与 NGINX 等 Web 服务器提供的反向代理功能相同。
链式微服务模式
对于单个服务或微服务,会有多个依赖关系,例如:销售微服务具有依赖产品微服务和订单微服务。链式微服务设计模式将帮助您根据您的请求提供综合结果。
微服务收到的请求:1,然后正在与微服务-2 通信,并且可能正在与微服务-3 通信。所有这些服务都是同步调用。
分支模式
微服务可能需要从多个源(包括其他微服务)获取数据。分支微服务模式是聚合器和链设计模式的混合,允许同时处理两个或多个微服务的请求/响应。被调用的微服务可以是微服务链。分支模式还可用于根据您的业务需求调用不同的微服务链或单个链。
客户端 UI 组合模式
当通过分解业务能力/子域来开发服务时,负责用户体验的服务必须从多个微服务中拉取数据。在单体世界中,过去只有一次从 UI 到后端服务的调用来检索所有数据并刷新/提交 UI 页面。然而,现在情况将不一样了。对于微服务,UI 必须设计为具有屏幕/页面的多个部分/区域的骨架。每个部分都会调用单个后端微服务来提取数据。像 AngularJS 和 ReactJS 这样的框架可以帮助轻松做到这一点。这些屏幕称为单页应用程序 (SPA)。每个团队都开发一个客户端 UI 组件,例如 AngularJS 指令,用于实现其服务的页面/屏幕区域。UI 团队负责通过组合多个特定于服务的 UI 组件来实现构建页面/屏幕的页面骨架。
数据库模式
定义微服务的数据库架构我们需要考虑以下几点。
服务必须是松散耦合的。它们可以独立开发、部署和扩展。
业务事务可以强制执行跨越多个服务的不变量。
某些业务事务需要查询多个服务拥有的数据。
有时必须复制和共享数据库才能扩展。
不同的服务有不同的数据存储要求。
每个服务的数据库
为了解决上述问题,必须设计一个微服务一个数据库;它必须仅对该服务是私有的。它只能由微服务 API 访问。其他服务无法直接访问它。例如,对于关系数据库,我们可以使用每服务私有表、每服务模式或每服务数据库服务器。
每个服务共享数据库
我们已经讨论过每个服务一个数据库对于微服务来说是理想的选择。这是微服务的反模式。但如果应用程序是一个整体并试图闯入微服务,那么非规范化就不那么容易了。在后期阶段,我们可以转向每服务数据库模式。每个服务共享数据库并不理想,但这是上述场景的可行解决方案。大多数人认为这是微服务的反模式,但对于棕地应用程序来说,这是将应用程序分解为更小的逻辑部分的良好开端。这不适用于绿地应用。
命令查询职责分离 (CQRS)
一旦我们实现了每服务数据库,就需要查询,这需要多个服务的联合数据。这是不可能的。CQRS 建议将应用程序分为两部分——命令端和查询端。
命令端处理创建、更新和删除请求。
查询端通过使用物化视图来处理查询部分。
事件源模式通常与其一起使用来为任何数据更改创建事件。物化视图通过订阅事件流来保持更新。事件溯源 大多数应用程序都使用数据,典型的方法是应用程序维护当前状态。例如,在传统的创建、读取、更新和删除(CRUD)模型中,典型的数据过程是从存储中读取数据。它包含锁定数据的限制,通常使用事务。
事件溯源模式
事件溯源模式 [8] 定义了一种处理由一系列事件驱动的数据操作的方法,每个事件都记录在仅附加存储中。应用程序代码将一系列事件发送到事件存储,这些事件强制描述数据上发生的每个操作,并在事件存储中保存它们。每个事件代表一组数据更改(例如AddedItemToOrder)。事件保存在充当记录系统的事件存储中。事件存储发布的事件的典型用途是在应用程序中的操作更改实体时维护实体的物化视图,以及与外部系统集成。例如,系统可以维护用于填充 UI 部分的所有客户订单的物化视图。当应用程序添加新订单、添加或删除订单上的商品以及添加运输信息时,可以处理描述这些更改的事件并将其用于更新物化视图。该图显示了该模式的概述。