该体系结构的核心组件是处理客户端请求的 Web 前端和执行资源密集型任务、长时间运行的工作流或批处理作业的辅助角色。 Web 前端通过消息队列与辅助角色进行通信。
通常合并到该体系结构中的其他组件包括:
- 一个或多个数据库。
- 存储来自数据库的值以便快速读取的缓存。
- 提供静态内容的 CDN
- 远程服务,如电子邮件或 SMS 服务。 这些功能通常由第三方提供。
- 用于身份验证的标识提供程序。
Web 和辅助角色都无状态。 会话状态可以存储在分布式缓存中。 任何长时间运行的工作都由辅助角色异步完成。 辅助角色可以由队列上的消息触发,或者在用于批处理的计划上运行。 辅助角色是一个可选组件。 如果没有任何长时间运行的操作,则可以省略辅助角色。
前端可能包括 Web API。 在客户端上,Web API 可以由进行 AJAX 调用的单页应用程序或者本机客户端应用程序使用。
何时使用此架构
通常使用托管的计算服务(Azure App Service 或 Azure 云服务)实施 Web 队列辅助角色体系结构。
请对以下情况考虑使用此体系结构样式:
- 具有相对简单的域的应用程序。
- 具有一些长时间运行的工作流或批处理操作的应用程序。
- 想要使用托管的服务而不是基础结构即服务 (IaaS)。
好处
- 体系结构相对简单,易于理解。
- 易于部署和管理。
- 清晰的关注点分离。
- 使用异步消息将前端从辅助角色中分离。
- 前端和辅助角色可以独立缩放。
挑战
- 如果没有经过仔细设计,前端和辅助角色可能变成难以维护和更新的庞大组件。
- 如果前端和辅助角色共享数据架构或代码模块,可能会有隐藏依赖关系。
- 成功将数据持久化到数据库之后,但在将消息发送到队列之前,Web 前端可能会发生故障。 这可能会导致一致性问题,因为辅助角色不会执行其逻辑部分。 事务发件箱模式等技术可用于帮助缓解此问题,但需要通过单独的队列将传出消息的路由更改到第一个“回环”。 支持此技术的一个库是 NServiceBus 事务会话。
最佳实践
- 向客户端公开经过良好设计的 API。 请参阅 API 设计最佳做法。
- 自动缩放以处理负载的更改。 请参阅自动缩放的最佳做法。
- 缓存半静态数据。 请参阅缓存的最佳做法。
- 使用 CDN 来托管静态内容。 请参阅 CDN 最佳做法。
- 适当时使用混合持久性。 请参阅[为作业使用最佳数据存储][polyglot]。
- 分区数据,可提高可伸缩性、减少争用以及优化性能。 请参阅数据分区最佳做法。
Azure App Service 上的 Web 队列辅助角色
本部分介绍使用 Azure App Service 的建议的 Web 队列辅助角色体系结构。
下载此体系结构的 Visio 文件。
工作流
Azure 应用服务 Web 应用作为前端实现,辅助角色作为 Azure Functions 应用实现。 Web 应用和函数应用都与提供 VM 实例的应用服务计划相关联。
可以为消息队列使用 Azure 服务总线或 Azure 存储队列。 (该图显示了 Azure 存储队列。)
Azure Cache for Redis 存储会话状态和需要低延迟访问的其他数据。
Azure CDN 用于缓存静态内容,如图像、CSS 或 HTML。
对于存储,请选择最符合应用程序需要的存储技术。 可能使用多个存储技术(混合持久性)。 为了说明这一点,该图显示了 Azure SQL 数据库和 Azure Cosmos DB。
有关详细信息,请参阅应用服务 Web 应用程序参考体系结构和使用 NServiceBus 和 Azure 服务总线生成消息驱动的商业应用程序。
其他注意事项
并不是每个事务都必须经过队列和辅助角色才能存储。 Web 前端可以直接执行简单的读取/写入操作。 辅助角色设计用于资源密集型任务或长时间运行的工作流。 在某些情况下,可能根本不需要辅助角色。
使用应用服务的内置自动缩放功能来扩大 VM 实例数。 如果应用程序上的负载遵循可预测的模式,请使用基于计划的自动缩放。 如果负载是不可预测的,请使用基于指标的自动缩放规则。
请考虑将 Web 应用和函数应用放入单独的应用服务计划中。 这样,它们就可以独立缩放。
使用单独的应用服务计划进行生产和测试。 否则,如果使用同一计划进行生产和测试,则说明测试正在生产 VM 上运行。
使用部署槽位来管理部署。 使用这种方法可将更新的版本部署到过渡槽,然后交换到新版本。 如果更新时出现问题,它还允许你切换回以前的版本。