专业的编程技术博客社区

网站首页 > 博客文章 正文

扩展无状态和有状态微服务时存在一些重要的区别

baijin 2024-08-17 10:53:38 博客文章 14 ℃ 0 评论

文章中有对你有帮助的记得在评论中回复哟

希望得到你的反馈

团队考虑采用微服务的最大原因之一是其快速扩展能力。微服务被设计、开发和部署为独立的服务,因此开发人员可以快速、轻松地扩展应用程序的部分功能。

要实现这一目标,只需执行以下两个步骤:

  1. 启动一个新的服务实例(也称为水平扩展)。
  2. 引入负载均衡器,将负载分配到两个服务实例之间。

这种方法对于无状态的微服务非常有效。但是,对于有状态的微服务来说,扩展并不像这么简单。

理解无状态和有状态微服务

在我们深入讨论扩展的概念之前,让我们先明确无状态微服务和有状态微服务之间的区别。

无状态微服务

无状态微服务不维护任何状态,也不在请求之间存储会话特定的数据。每个请求被无状态微服务独立处理,不依赖于之前的交互。

它们基于"共享无关"的概念运作。这使得它们可以在多个实例之间进行水平扩展,而不会影响其功能。

有状态微服务

有状态微服务在多个请求之间维护和管理会话特定的状态。它们存储数据并维护上下文,使得它们能够在交互之间跟踪和记忆信息。

如何扩展无状态微服务?

与有状态微服务不同,扩展无状态微服务是比较直接的。有几种推荐的架构模式可用于扩展无状态微服务。

  • 水平扩展

水平扩展是扩展无状态微服务最常见的方法之一,也称为"横向扩展"。水平扩展涉及添加更多的微服务节点(或实例),从而增加服务的整体处理能力。

例如,考虑下面的图示:

例如,假设您正在使用AWS Lambda构建一个微服务。在这种情况下,微服务将进行水平扩展,并根据用户负载创建新的微服务实例(函数)来处理传入的用户请求。

重要的是要了解在无服务器环境中,水平扩展是自动完成的。像AWS Lambda这样的服务会自动进行水平扩展,并创建新的函数实例,以确保满足负载需求。

然而,如果您正在通过虚拟机或使用Docker/Kubernetes容器进行服务器部署,您必须配置一个扩展策略,该策略将根据给定的阈值来启动新的微服务实例。同时,不要忘记在负载减轻时进行缩减,否则您的财务主管可能对此不满意。

  • 负载均衡

有时,仅仅启动新的微服务实例是不够的。您的应用程序传入请求必须根据每个服务所承受的负载智能地路由到每个微服务实例。这就是负载均衡器发挥作用的地方。

负载均衡器将传入的请求分发到多个微服务实例上。它确保负载在每个微服务实例之间均匀分布,以确保没有实例过载,从而提高服务的可用性。负载均衡器还可以检测无响应的节点,并停止向这些节点发送新的请求。

AWS提供的应用负载均衡器是其中的一个常见应用场景。

如上所示,两个微服务实例(实例A和B)通过应用负载均衡器(ALB)有一个入口点供用户进行交互。ALB会根据每个实例的负载情况将请求路由到实例A或B。

由于是无状态的,将请求路由到两个微服务实例变得非常简单,因为每个实例可以在不考虑任何先前状态的情况下处理任何请求。

  • 自动扩展

自动扩展在扩展无状态微服务方面起着重要作用。例如,考虑每天根据不同的工作负载来扩展一个服务。有些天,系统可能处理百万用户,但在极少数情况下,可能会处理高达一千万用户。在这个级别手动扩展您的微服务和数据库几乎是不可能的。而这正是自动扩展发挥作用的地方。

通过自动扩展,您可以配置基础设施,根据预定义的指标(如CPU利用率、内存使用率或网络流量)自动添加或删除实例。这使得您的微服务可以动态适应需求的变化,确保性能和成本效率的最优表现。

这不仅适用于实例,也适用于数据库。众所周知,建议每个微服务使用一个单独的数据库,以确保您可以根据需求随时扩展数据库的某个部分。

举个例子,想象一种情况,您需要为您的微服务扩展数据库。由于您的服务具有不可预测的工作负载,您可以设置一个自动扩展策略,自动增加和减少数据库吞吐量,以满足需求。

此外,您还可以将自动扩展策略应用于Kubernetes集群或VM集群,根据负载自动启动或删除微服务的实例。

  • 缓存

将频繁访问的数据存储在具有快速数据访问速度的内存数据库中,是扩展微服务以提高性能的一个很好的方法。例如,考虑以下图示:

上面的图示展示了一个简单的微服务从图像转文本转换器中获取数据。

值得注意的是,“图像转文本转换器”是一个高度资源密集型的资源,在将单个图像转换为文本时需要很长时间。

因此,一旦图像被转换为文本,其引用以及文本必须被存储在缓存中,以便快速访问。然后,当用户请求相同图像的文本表示时,可以从缓存中返回,从而避免长时间的等待,确保在您的无状态微服务上实现更好的可扩展性。

请注意,您可以与多个扩展的微服务实例共享缓存,但是您需要注意数据完整性和冲突写入,并且建议在这种情况下使用分布式读写锁。

如何扩展有状态的服务?

扩展有状态的微服务并不像扩展无状态的微服务那样简单。除了扩展服务之外,您还必须考虑在扩展过程中维护数据的一致性。这就是问题的难点所在。

不过,以下是一些推荐的架构模式,可以帮助您更好地扩展有状态的微服务。

  • 垂直扩展

垂直扩展有时被称为“向上扩展”。垂直扩展是升级单个微服务实例的配置,以改善其性能。通过采用垂直扩展方法,您确保不会创建新的服务实例,从而确保您的数据在单个有状态服务内保持一致性。

如上所示,当您进行垂直扩展时,实际上是增加了现有实例的容量。例如,如果您最初创建实例时内存为16GB,可以通过增加其内存到64GB 来改善性能。

然而,重要的是要了解垂直扩展也有其限制。例如,大多数服务器运行的内部硬件都有其扩展限制。有时,系统可能只支持32GB的内存。这意味着无论如何,您都无法将内存提升到超过32GB。

在这种情况下,建议创建一个具有更好配置(作为基本设置)的新实例,并停用低配置的服务。

  • 有状态服务发现与负载均衡

对于有状态的微服务,建议使用支持它们的服务发现工具。这样做可以实现为有状态应用程序设计的负载均衡器,它可以智能地将请求路由到特定的实例,并考虑会话关联。

这确保属于特定会话的请求始终被路由到同一个服务实例,从而可以在不考虑数据同步的情况下扩展有状态的微服务。

  • 数据复制(Data Replication)

数据复制在扩展有状态的微服务中起着至关重要的作用。这种技术确保在服务实例故障或灾难发生时,数据具有高可用性、持久性和可恢复性。

负责数据复制的开发团队可以采用主动-主动(Active-Active)或主动-被动(Active-Passive)策略,并使用不同类型的主数据库和副本数据库策略。通过这样做,可以实现有状态的微服务:

提高读取扩展性:数据复制允许您创建多个主数据库的副本。通过在这些副本之间分配读取操作,您可以显著提高读取扩展性和速度,使每个副本可以独立处理读取请求。然而,值得注意的是,这种性能改进是以一致性的牺牲为代价的,因为这是一种最终一致性的方法,而不是强一致性的方法。 提高可用性:在多个实例之间复制数据可以提高数据的冗余性。如果一个节点因故障而不可用,其他副本可以继续提供读取操作,并通过自动故障切换维护系统的可用性。

对有状态微服务进行扩展是一项具有挑战性的任务,需要深思熟虑的方法和对数据一致性权衡的理解。尽管无状态微服务可以通过水平扩展和负载均衡相对轻松地进行扩展,但有状态微服务需要更仔细的规划和考虑,以实现高效和可靠的扩展性。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表