引言
微服务之所以受到赞扬,是因为它们允许每个功能独立增长。虽然它们在B2C世界中大放异彩,因为在B2C世界中,每个用户的流量都是一致的,但B2B经常与其用户之间独特的流量差异作斗争。在这个点击诱饵的标题背后,我将向您展示一个更简单的解决方案,称为池体系结构,旨在为每个客户端量身定做扩展!
让我们以上图这个水族馆为例。图里虽有很多小鱼和鲸鲨共用鱼缸但别担心,尽管它们是鲸鲨,但也只以浮游生物为食。能够与珊瑚礁鱼和平共处。相反,食品分配却是一直存在的问题。
服务看作鱼缸
想象一下你的服务就是这个鱼缸。每个客户都是一条鱼,他们都共享相同的基础设施(水和食物)。
你不能一条一条地喂鱼,唯一的选择就是把食物倒进罐子里。
如果你放得不够多,鲸鲨可能会在较小的鱼之前吃掉所有东西,让它们挨饿。
如果你放了太多的食物,每个物种都会吃到他们需要的东西,但一些剩余的食物会浪费掉。
这正是CPU正在发生的情况。如果客户大量使用你的服务,他可能会拒绝其他客户(吃光所有食物)。
如果你有太多的实例,你就是在浪费钱。
就好比,AWS资源在客户端之间共享。
这意味着你可以在与Netflix相同的数据中心内使用相同的CPU。
当他们发布一个新节目时,你可能最终会争夺资源。这就是一个每个客户端共享相同的基础设施的服务。
一条鱼,一个鱼缸
单元架构背后的思想是将您的系统拆分成单元:"从设计和实现到部署分组的组件集合。一个单元是独立可部署、可管理和可观察的。(参见 WSO2网站)
领域驱动开发(DDD)基于领域划分单元,而微服务则根据功能划分单元。
确定正确的边界或单元的合适大小始终是一项具有挑战性的任务。单元体系结构的初次迭代通常进展缓慢,不允许快速扩展。
在池体系结构中,我们扩展了单元的概念。我们为边界定义了一个简单的规则:一个客户一个单元。换句话说,每个客户都运行其专用的单体,具有保留的基础设施,允许根据他们的需求进行扩展。
如果我们延续这个比喻,现在每个客户可以拥有不同的水温,危险物种可以有自己的小水缸,而鲸鱼可以有一个巨大的水缸。
食物不再是问题,因为你可以选择填充哪个水缸。这个比喻强调了在池体系结构中,每个客户都可以根据其独特的需求和特性进行定制和配置,就像水族馆中的不同鱼类需要不同的环境一样。
使用传统的服务三层体系结构:
这种体系结构通常包括以下三个层级:
- 表示层(Presentation Layer): 这是用户与系统交互的界面层。它负责显示信息给用户并接收用户的输入。这可能是一个用户界面、Web界面或其他形式的用户交互界面。
- 业务逻辑层(Business Logic Layer): 也称为服务层,这一层包含了应用程序的业务逻辑。它处理应用程序的具体业务规则和功能。在这个层级,数据被处理、转换,以满足应用程序的需求。
- 数据访问层(Data Access Layer): 这一层负责与数据存储进行交互,包括数据库或其他数据存储系统。它处理从业务逻辑层传递下来的数据,并执行数据库操作。
👍 优势:
- 只在需要的地方花费资金,根据客户规模进行扩展: 池体系结构允许资金的有针对性使用,确保每个客户都可以根据其规模和需求进行灵活的扩展。
- 如果客户流失,只需安全地删除其基础设施: 当客户不再使用服务时,可以轻松地安全删除其专用基础设施,从而避免不必要的资源浪费。
- 限制事故的影响范围,崩溃只影响一个池: 在发生故障或事故时,影响仅限于受影响的池,不会波及到其他客户的服务。
- 增加安全/隐私层,客户数据永远不会共享: 池体系结构提供了额外的安全层,确保客户数据始终保持隔离,不会与其他客户共享。
- 部署比微服务更容易,只需部署整个单体(复制/粘贴你的terraform): 相对于微服务,池体系结构的部署更加简单,只需复制和粘贴整个单体,使用类似 Terraform 的工具进行管理。
- 根据客户的时区部署更改,避免任何停机时间: 可以根据客户的时区部署变更,以最小化对客户的影响,从而避免停机时间。
鲸鱼是什么? 🐳
在文中,"鲸鱼"是指一个具有特殊需求或特性的大型客户,他们需要一个专用的池(Dedicated Pool)。这个术语可能基于技术或业务标准来定义。
技术标准可能包括:
- 运行给定请求数量的客户。
- 执行缓慢或昂贵的请求,比如上传相对于下载、读取相对于写入等。
业务标准可能包括:
- 支付高额费用的客户。
- 具有合规性要求的客户。
迁移
大多数初创公司在初期选择优化开发速度和工程成本。这就是为什么很多初创公司采用单体架构的原因。但随着它们的成长,一些客户规模扩大,成为重度用户,对共享基础设施产生影响。
将用户从共享基础设施迁移到专用基础设施并非易事。以下是迁移的一个示例:
- 步骤1:迁移网络层: 为用户提供指向旧基础设施的专用DNS。
- 步骤2:迁移计算层: 使他们在专用实例上运行,但保持共享数据库。
- 步骤3:迁移数据层: 将所有数据从共享数据库移动到他们自己的数据库。
根据经验,最后一步是最复杂的部分。你希望提取给定用户的所有数据,并将其复制到另一个数据库。通常需要使用复杂的查询仅加载所需的数据。在涉及索引、复合键等方面,情况会更加复杂。
简要说明:
- 网络层迁移: 通过为用户提供专用DNS,将用户的网络连接指向旧基础设施。
- 计算层迁移: 将用户的计算任务迁移到专用实例上,但仍然使用共享数据库。
- 数据层迁移: 将用户的所有数据从共享数据库移动到他们自己的数据库。
在某些方面,池体系结构的迁移看起来类似于拆分单体架构。
在Sam Newman的书中,他提到了将单体架构迁移到微服务的技术。它们通常都需要一些代码修改和复杂的业务逻辑更改。
相比之下,池体系结构的迁移往往更为经济,因为它主要依赖于编写基础设施即代码(Infrastructure as Code
)。
简而言之,与将单体拆分为微服务相比,池体系结构的迁移更注重于通过编写基础设施的代码来实现,而不是进行复杂的业务逻辑和代码修改。这使得迁移过程更为直接和成本效益。
👎 缺陷:
- 专用基础设施不是定制代码: 所有客户都应该共享相同的代码。要小心,池体系结构并不是一种根据客户进行代码定制的方式。当你部署修复时,请部署所有客户。从长远来看,如果尝试维护多个客户代码库,这将使你的工作变得困难。由于代码保持不变,你可以使用数据库或环境变量来满足特定需求,如DNS名称。避免将CSS放入数据库以获得不同的外观和感觉。你不是在构建CMS(内容管理系统)。
- 更难维护: 日志和监控不再集中。你需要多个帐户连接到每个客户环境,并找出问题所在。你不再拥有跨客户的分析。
- 提前迁移: 尽管可能很诱人,但是池体系结构需要大量工作来实施。你需要工具。例如,Terraform脚本以确保基础设施作为代码进行维护。因此,当你进行更改时,每个客户都可以轻松部署。
- 最初更昂贵: 首先为每个客户设置特定基础设施的成本将是重要的。最初拥有两个小型数据库比一个中型数据库更昂贵。这可能是在初始阶段的高成本。
总结
虽然池体系结构的概念提供了一个引人注目的替代方案,与无处不在的微服务方法相比,必须承认并没有一种适合所有情况的解决方案。在追随最新趋势之前,开发人员和架构师必须谨慎行事。
就像在水族馆的比喻中一样,我们为服务构建的生态系统必须经过仔细的平衡。对于B2C平台有益的东西可能对B2B服务产生不同的结果。我们必须考虑我们客户的个体需求。
因此,在采用任何新的架构模式时,要既有创新的热情又有健康的怀疑态度。提出正确的问题:它是否节省资源?现在是否是合适的时机?迁移的成本是多少?
为了获得更务实的见解,请务必关注。保持信息更新,保持怀疑态度,并负责任地继续构建。这种谨慎和理性的方法有助于确保任何新的架构选择都是有根据的,并能够满足特定场景和需求。