使应用程序可缩放
现在,你已了解有关为业务增长做好准备的基本知识,并了解了进行容量计划时需要考虑的因素,可以继续接受“尽可能地提升应用程序的缩放能力”这一挑战了。
体系结构评审
需要记住的一个要点是,应对系统进行定期体系结构评审。
你知道可以应用基础结构即代码这样的做法来改进云资源的部署方式。 你会定期更新和改进应用程序代码,对于基础平台资源也应该这么做。
进行体系结构评审可以帮助你确定需要改进的方面。
Azure 体系结构中心提供丰富的资源来帮助你在云中架构应用程序,单击以下链接可转到应用程序体系结构指南,其中提供了许多有关可伸缩性的建议:
场景:Tailwind Traders 体系结构
评估体系结构和应用程序的第一步 - 不仅要确定弱点所在,还要识别其优势。 它有什么优点?
再看看上一单元中看过的场景。 再次以该组织的体系结构图为例。
他们将应用程序分解为较小的微服务,其中某些服务是 Azure Kubernetes 服务上的固定容器,也可以在 VM 或应用服务上运行。 你将使用某些具有“固有可伸缩性”的服务,例如 Functions 和逻辑应用。
这种更改是好的,但又一些改进会提升应用程序的可伸缩性。 举个例子,现在我们专注于“产品”服务。 在图中,产品服务在 Kubernetes 中运行,但在进行本次解释时,我们假设它在 Azure 上的 VM 中运行。 无论应用程序在服务器、应用服务还是容器中运行,都可对其应用缩放的概念,只是实施可能略有不同。
该产品当前在单个 VM 上运行,后者连接到单个 Azure SQL 数据库。 你需要让这个 VM 能够横向扩展。可以使用 Azure 虚拟机规模集,创建并管理一组完全相同的、负载均衡的 VM,从而实现这一目标。 现在你已拥有多个 VM 了,因此需要引入负载均衡器在这些 VM 之间分配流量。
虚拟机规模集
通过对单个 VM 应用虚拟机规模集,可以获得以下优势:
- 可以根据主机指标、来宾内指标、Application Insights 或按计划自动缩放。
- 可以使用可用性区域 (AZ),它们是一个 Azure 区域内的独立数据中心。 在 AZ 的支持下,你可以将 VM 分散到多个 AZ,从而使应用程序更可靠,并针对数据中心故障提供保护。 规模集中的新实例自动平均分配到多个 AZ。
- 可以更轻松地添加负载均衡器。 虚拟机规模集支持使用 Azure 负载均衡器进行基本的第 4 层流量分发。 它们还支持 Azure 应用程序网关,实现更高级的 L7 流量分发和 SSL 终止。
实施规模集之前,需要考虑一些重要的因素。 具体而言:
- 避免实例“粘性”,使客户端不至于“陷于”特定后端。
- 从 VM 删除持久数据并将其存储到别处,例如 Azure 存储或数据库中。
- 针对缩减进行设计。 同样重要的是,应用程序可以轻松地缩减规模。 它不仅必须能够顺利向处理流量的服务器池中添加更多实例,还必须要能轻松应对因负载降低而导致的实例突然中止。 缩放的纵向缩减方面经常被忽视。
分离
你通过规模集添加了更多的 VM。 在需要扩展时,横向扩展是典型解决方案。但只能对单个指标进行缩放,这种解决方案不一定适用于你的产品服务所执行的所有任务。
在我们的场景中,产品服务有其职责。 它获取一个产品图像,然后上传该图像。 它对图像进行转码,并将其存储为几种不同大小的缩略图、目录中的图片等。 图像处理是 CPU 密集型任务,但常规用途是内存密集型任务。
图像处理是异步任务,可细分为后台作业。 可使用队列来分离图像处理服务以便完成此操作。 通过分离,可独立缩放两项服务 - 一项针对内存(产品服务),另一项(图像处理服务)针对 CPU,或均衡队列长度以让另一个规模集使用这些详细并处理图像。
通过队列缩放
Azure 有两种类型的队列服务:
- Azure 服务总线队列 - 更高级的队列服务,属于更广泛的 Azure 服务总线产品,提供发布/订阅和更高级的集成模式。
- Azure 存储队列 - 以 Azure 存储为基础构建的基于 REST 的简单队列接口。 它提供可靠、持久的消息传输服务。
在此场景中,你的要求很简单,因此可以使用 Azure 存储队列。 根本不需要缩放产品层,因为你已经分离了这一后台任务。
内存中缓存
改进应用程序性能的另一种方式是实施内存中缓存。
现在你知道了,性能不完全等同于可伸缩性,但改进应用程序的性能可以降低其他资源的负载。 这种改进意味着也许不需要那么快进行扩展。
Azure Cache for Redis 是托管的 Redis 服务。 Redis 可用于许多模式和用例。 就此场景中的产品服务而言,你很可能要实施旁路缓存模式。 在此模式中,根据需要将项从数据库加载到缓存中,以提升应用程序的性能并降低数据库的负载。
还可将 Redis 用作消息传输队列,用于缓存 Web 内容或用户会话。 这种类型的缓存可能更适用于系统中的其他服务,例如购物车服务,以便在 Redis 中按会话存储购物车数据,而不使用 cookie。
缩放数据库
现在你已提升计算资源的缩放能力,来看看数据库吧。 在此场景中,你正在使用 Azure SQL 数据库,它是 Azure 提供的一种托管 SQL 服务器产品。
与非关系数据库相比,关系数据库更难横向扩展。 要扩展数据库,首先可以纵向扩展数据库的大小。 这种重设大小可以很容易地完成,平均停机时间不到四秒钟。 通过在 Azure SQL 中使用简单的 API 调用,或者通过在门户中使用滑块。
如果这种增大不能满足要求,根据流量特性,可能适横向扩展对数据库的读取。 使你能够将读取流量路由到只读副本。
注意
使用 Azure SQL 时,如果使用高级层或业务关键层,则默认启用读取横向扩展。 在基本或标准层上不能启用它。
必须在代码中实现此更改。 操作步骤如下。
#Azure SQL Connection String
#Master Connection String
ApplicationIntent=ReadWrite
#Read Replica Connection String
ApplicationIntent=ReadOnly
#Full Example
Server=tcp:<server>.database.windows.net;Database=<mydatabase>;ApplicationIntent=ReadOnly;User ID=<myLogin>;Password=<myPassword>;Trusted_Connection=False; Encrypt=True;
更新数据库连接字符串中的 ApplicationIntent
属性,以指定要连接的服务器。 如果要连接到副本,请使用 ReadOnly
;如果要连接到主控副本,请使用 ReadWrite
。
因为此命令必须在代码中实现,所以这种解决方案可能不适用于你的情况。 如果每个产品服务都需要读取和写入功能,该怎么办?
在这种情况下,可以尝试使用分片横向扩展 SQL DB。
数据库分片
如果在纵向扩展或实现只读副本后,数据库资源仍不能满足系统的需求,接下来可以分片。
分片是一项可跨许多独立数据库分发大量相同结构数据的技术。 需要分片的原因有很多。 例如:
- 数据总量过大而超出单个数据库的限制范围。
- 整个工作负载的事务吞吐量超出单个数据库的容量。
- 出于合规性原因,单独的租户需要驻留在不同的物理数据库上(这一要求与缩放没有太大关系,而是使用分片的另一种情况。)
应用程序将相关数据添加到相关分片,从而使系统的伸缩性超越单个数据库的约束。
Azure SQL 提供 Azure 弹性数据库工具。 这些工具帮助你根据自己的应用程序逻辑在 Azure 中创建、维护和查询分片的 SQL 数据库。