在硅三明治架构中,在研究架构特性后,我们确定单量子就足以实现该系统。此外,这是一个简单的应用程序,没有庞大的预算,所以一个简单的单体架构足矣。
然而,我们为硅三明治创建了两种不同的组件设计:一个基于领域划分,另一个基于技术划分。考虑到解决方案的简单性,我们将为每个解决方案创建设计并覆盖权衡。
18.3.1 模块化单体
一个模块化单体使用单个数据库构建以域为中心的组件,部署为单个架构量子。硅三明治的模块单体设计如图 18-1 所示。
在图 18-1 中,这是一个带有单个关系型数据库的单体,通过一个基于 Web 的用户界面(考虑到移动设备的精心设计)实现,以降低总体成本。架构师在前面确定的每个领域都作为组件出现。如果时间和资源足够的话,架构师应该考虑创建与领域组件相同的表和其他数据库资产的分离,这样,如果将来的需求需要的话,架构师就可以更容易地迁移到分布式架构。
因为架构风格本身并不是可定制的,所以架构师必须确保该特性成为领域设计的一部分。在这种情况下,架构师设计一个覆盖端点,开发人员可以在该端点上上传单独的定制。相应地,架构师必须确保每个领域组件都引用每个可定制特征的覆盖组件—这将是一个完美的适应度函数。
图 18-1:硅三明治的模块化单体实现
18.3.2 微内核
架构师在硅三明治中确定的架构特征之一是可定制性。查看域 / 架构同构,架构师可以选择使用微内核来实现它,如图 18-2 所示。
在图 18-2 中,核心系统由领域组件和一个关系型数据库组成。与前面的设计一样,领域和数据设计之间的仔细同步将允许未来将核心迁移到分布式架构。每个定制都出现在一个插件中,常见的定制出现在一组插件中(带有相应的数据库),此外还有一系列本地定制,每个定制都有自己的数据。因为没有一个插件需要与其他插件耦合,所以它们可以各自维护自己的数据,从而使插件彼此分离。
这里的另一个独特设计元素使用了前端后端(BFF) 模式,使 API 层成为一个瘦微内核适配器。它从后端提供一般信息,BFF 适配器将一般信息转换为适合前端设备的格式。例如,iOS 的 BFF 将从后端获取通用输出,并根据 iOS 本地应用程序的期望对其进行定制:数据格式、分页、延迟和其他因素。构建每个 BFF 适配器允许最丰富的用户界面和扩展能力,以支持未来的其他设备—这是微内核风格的好处之一。
图 18-2:硅三明治的微内核实现
两种硅三明治架构之间的通信可以是同步的—架构不需要极端的性能或弹性要求— 而且操作都不会很长。
分布式案例研究:前进,前进,消失
“前进,前进,消失”(GGG) 卡塔提出了更有趣的架构挑战。基于 8.7 节中的组件分析, 该架构需要针对架构的不同部分使用不同的架构特征。例如,架构特征(如可用性和可伸缩性)在角色(如拍卖师和投标人)之间会有所不同。
GGG 的需求还明确规定了某些雄心勃勃的规模、弹性、性能级别,以及许多其他棘手的运营性架构特征。架构师需要选择一种模式,这种模式允许在架构内的细粒度级别上进行高度定制。在候选的分布式架构中,低级事件驱动或微服务符合大多数架构特征。在这两者中,微服务更好地支持不同的运营性架构特征—纯事件驱动的架构通常不会因为这些运营性架构特征而分开,而是取决于通信风格、编排与编制。
在微服务中实现指定的性能将是一个挑战,但是架构师通常可以通过设计来克服架构的任何弱点。例如,虽然微服务自然提供了高度的可伸缩性,但是架构师通常必须解决由过多编制、过于激进的数据分离等引起的特定性能问题。
使用微服务的 GGG 实现如图 18-3 所示。
图 18-3:GGG 的微服务实现
在图 18-3 中,每个被识别的组件成为架构中的服务,与组件和服务粒度相匹配。GGG 有三个不同的用户界面:
投标人
网上拍卖的众多投标人。
拍卖师
每场拍卖有一个拍卖师。
流
负责向投标人提供视频流和竞标流的服务。注意,这是一个只读流,允许在需要更新时不可用的优化。
以下服务出现在这个 GGG 架构的设计中:
竞标捕获组件
捕获在线投标人条目并异步地将它们发送到竞价跟踪组件。此服务不需要持久性, 因为它充当在线竞标的管道。
竞标流组件
以高性能、只读的方式将出价流回在线参与者。
竞标跟踪组件
跟踪来自拍卖捕获和竞标捕获。这是将两种不同的信息流统一起来的组件,使出价尽可能接近实时。注意,此服务的两个入站连接都是异步的,允许开发人员使用消息队列作为缓冲区来处理非常不同的消息流速率。
拍卖捕获组件
为拍卖师出价。8.7 节中的量子分析结果导致架构师将竞标捕获组件和拍卖师捕获组件分开,因为它们具有完全不同的架构特征。
拍卖会组件
管理单次拍卖的工作流。
支付组件
第三方支付提供商在拍卖会结束后处理支付信息。
视频捕获组件
捕获现场拍卖的视频流。
视频流组件
将拍卖视频流到在线投标人。
架构师小心地确定了此架构中的同步和异步通信风格。选择异步通信主要是为了适应服务之间不同的运营性架构特征。例如,如果支付服务每 500 毫秒只能处理一次新支付, 并且大量拍卖同时结束,那么服务之间的同步通信将导致超时和其他可靠性问题。通过使用消息队列,架构师可以为架构中脆弱的关键部分增加可靠性。
最终,这个设计解析为 5 个量子,如图 18-4 所示。
图 18-4:GGG 的量子边界
在图 18-4 中,设计包括支付、拍卖师、投标人、投标人流和竞标跟踪组件等量子,大致对应于各个服务。图中的容器堆栈表示多个实例。在组件设计阶段使用量子分析使架构师更轻松地识别服务、数据和通信边界。
请注意,这不是 GGG 的“正确”设计,而且肯定不是唯一的设计。我们甚至不认为它是可能的最佳设计,但它似乎具有最不糟糕的权衡。选择微服务,然后智能地使用事件和消息,允许架构最大限度地利用通用架构模式,同时仍然为未来的开发和扩展构建了基础。