这是我书《建筑元模式》这本书中的一个章节。欢迎任何反馈。这本书是免费的(CC BY 许可),可以通过以下链接免费下载(PDF 和 ePub)从 GitHub 下载。
多面手. 使用一个第三方软件来应对多种需求。
版本:
- 消息总线 [EIP],
- API 网关 [MP],
- 事件中介器 [FSA],
- 企业级服务总线 [FSA],
- 服务网格 [FSA],
- 基于空间架构的中间件 [SAP, FSA].
结构模式:两个或多个扩展模式组合成一个单一组件。
类型: 扩展程序。
参考文献:主要参考的是[FSA]和Microsoft API网关。
两个或三个元模式可以混合在一起形成一个 集成组件,这通常是一个现成框架,旨在覆盖(并隐性满足)尽可能多的项目需求,以确保它永远不会被项目抛弃。一方面,这样的框架可以大大加快开发速度。另一方面,它会将你限制在其适用范围之内,并限制你的选择。
性能一个_组合组件或复合组件_往往会提高性能,因为它消除了替代它的各个组件之间的网络跃点和数据序列化过程。它通常也会被高度优化。然而,这只有在你确实需要它提供的所有功能时才重要,否则你可能会发现你运行的软件对于手头的任务来说过于复杂且运行缓慢。
依赖组合组件包含了各组成部分的依赖。
适用范围组合模式可以很好地应用于:
- 一系列类似项目。如果你的团队熟悉该技术并了解其局限性,将能够高效且安全地使用。
- 小型到中型范围。一个现成的框架可以解决基础设施方面的顾虑。无需思考、决策、浪费时间。
在以下情况中,最好避免使用结合模式:
- 研究与开发。你可能会发现,当所选技术已经深深嵌入你的代码和基础设施中时,它可能过于局限或不适合你的实际情况。
- 大型项目。大多数组合模式中都包含一个 编排器,随着项目的扩大,编排器往往会变得难以管理(可能需要某种形式的拆分,参见 编排器 的变体)。
- 长期项目。随着行业的变化,你可能会遇到供应商锁定的情况,使你选择并集成的技术变得过时。
这些组合起来的组件在结构和性质上有所不同:
消息总线 [消息队列集成模式 EIP]消息总线通常指的是消息传递总线,它是软件工程和IT领域中消息队列集成模式的一种实现。
一个中间件,它为每个服务提供一个适配器,使不同协议的服务能够通信。
API网关 [MP] 注:[MP]需根据具体上下文进行解释说明。一个 API网关(API Gateway)是一个处理客户端请求(并封装客户端协议,如HTTP、HTTPS等)的组件,就像一个网关(一种代理)。它像一个 API组合器 或流程管理器(编排器)那样,将每个客户端请求拆分成多个对底层服务的请求。
如果 API 网关的编排逻辑变得更复杂,将该组件拆分为一个独立的网关和编排器是有意义的,将后者重写为一个自定义的应用服务。当这些客户端的工作流程和协议差异很大时,会为每种客户端类型使用一个单独的 API 网关,从而形成前端后端分离架构(BFF架构)。细胞架构依赖 API 网关来隔离各个细胞。
例如:来自 Microsoft 的一篇详细文章。Microsoft
事件中介者 [FSA]_事件中介_是一种编排型的中间件。它不仅接收客户端请求并将每个请求转化为多步骤流程(就像编排器所做的那样),而且还管理服务实例,并作为请求传输到服务并接收确认的桥梁。此外,它似乎了解系统中所有类型的消息以及每条消息必须转发到哪个服务,这导致了复杂性集中于单一组件,甚至违背了职责分离的原则。[FSA]建议通过在接下来的各个维度上使用多个_事件中介_来解决此问题。
- 客户端应用程序或有界上下文,通过业务子域划分事件代理的责任。
- 用例的复杂性,简单场景由一线事件代理处理,对于更复杂的场景,则直接交给二线和三线的代理处理,这些代理则会用到更复杂的编排引擎。
导致多个中间件连接至同一组服务,这很奇怪。
这种模式似乎已经相当成熟且形成了一定的标准,但对于更大、更复杂的项目来说,这种模式可能会变得相当混乱。这样的情况可以通过将中间件分离出来,并将其与编排器分开处理,同时将其分解为后端与前端对接(Backends for Frontends)来解决。
例如:[FSA]章中关于事件驱动架构章节的中介者模式。
企业服务总线(一种用于集成和管理不同应用程序间通信的技术) (ESB) [FSA]一种由消息总线(每个服务都有一个适配器)和事件中介(内置编排器)组成的架构,使这种中间件成为系统的核心。它在组织中的核心地位及其复杂性是导致企业面向服务架构(SOA)衰落的主要原因之一。
示例:面向服务的架构(FSA)中的以编排驱动的服务架构,其诞生及消亡,详见(出处)以及(出处),Neal Ford 所述。
服务网状 [FSA]一种中间件,它为每个服务使用一个边车(适配器)来处理如日志记录、可观测性、加密、协议转换等横切关注点。服务可以访问其_边车_而不会影响性能和稳定性,因为它们与服务在同一台机器上运行。所有部署的_边车_共同构成一个系统范围的逻辑共享层:尽管_边车_在物理上是分开的,但它们是相同的且无状态,因此,访问一个_边车_的服务可以被视为访问所有边车。
服务网格也负责动态扩展能力(当负载增加时,它会创建新实例;当实例空闲时,它会销毁它们)并负责服务的故障恢复。此外,它为微服务相互通信提供了消息基础设施。
空间架构中的中间件,[SAP, FSA]_基于空间的架构_依赖于最复杂的软件中间件——它包含了如下4种扩展模式:
- Messaging Grid 是一个代理,接收、预处理并持久保存客户端请求(作为网关)。简单的请求会被转发到负载较轻的处理单元,而复杂的请求会被分发到处理网格。
- _处理网格_是一个编排器,管理复杂请求的多步骤流程。
- _数据网格_是一个分布式内存中的数据库。它由节点组成,这些节点与_处理单元_的实例共存,使得数据库访问速度非常快。然而,速度和可扩展性的提高是以牺牲稳定性为代价的——任何存储在内存中的数据都有可能会丢失。因此,_数据网格_会将所有写入备份到较慢的外部数据库。
- _部署管理器_是一个中间件,它创建和销毁与数据网格节点相关联的_处理单元_的实例,就像_服务网格_为_微服务_所做的那样。然而,与_服务网格_不同,它不提供消息基础设施,因为_处理单元_通过数据网格交换数据,而不是通过消息传递。
_太空架构_的_中间层_有四个层次,这些层次相对独立。它们一起形成一个这样的系统,比_微服务_更易于扩展,也更复杂。
演变涉及编排(如API网关、事件中介和企业服务总线)的模式可以通过部署组件的多个版本例如这样可以实现大部分编排器元模式的演进。还有特别的一种演进:
将组合组件更换为几个专门的组件
分成专门的层次模式:层次。
目标:突破供应商锁定[DDD(领域驱动设计)],增强灵活性。
前提条件:你得有很多空闲时间。
如果你觉得你的系统依赖的组合式组件无法完全满足需求,或者价格过高、不够稳定,那么你可能想要用一些单一功能的通用工具或自制实现替换它,这样就可以始终按需调整。
好的地方:
- 它是免费的。
- 你将拥有你的代码所有权。
- 你所写的一切,只要你愿意投入时间维护,就能一直满足你的需求。
不足:
- 这会耗费大量工作。
- 性能可能会下降,因为请求路径上的组件会变得更多,而且你使用的工业级框架可能已经进行了高度优化。
摘要
一个“集成组件”是一个现成的框架,可能加速开发,但也会限制你的项目必须遵循其规范,而不会考虑你的实际需求。
参考文献[DDD] 领域驱动设计:应对软件核心复杂性。Eric Evans。Addison-Wesley(2003年)。
[EIP] 企业集成模式缩写.Gregor Hohpe 和 Bobby Woolf (格雷戈尔·霍普,鲍比·伍尔夫). Addison-Wesley (2003).
[FSA] 软件架构基础:工程导向。 马克·理查兹与尼尔·福特。O’Reilly 出版社(2020)。
[MP] 微服务架构模式:包含Java示例。Chris Richardson, Manning Publications (2018).
[SAP] 注:软件架构模式。马克·理查兹。奥莱利出版社。(2015年)