设计地理分散式应用程序体系结构
当网络组件将请求路由到多个区域以减轻区域性中断的影响时,必须设计可在主区域和备用区域中响应这些请求的应用程序服务。
回想一下,先前我们计划用优先级后端分配来配置 Azure Front Door。 我们将美国东部区域指定为主要区域,将美国西部区域指定为备用区域。 发生区域性故障时,请求将路由到未发生故障的区域中的应用服务。 必须在每个区域中配置资源,以支持用户访问、复制存储和应用程序代码的故障转移。
在这里,我们将检查解决方案中的应用程序服务,确定是否需要对其进行修改以在多区域体系结构中运行。 具体而言,我们将研究 Active Directory、静态内容存储、Web 应用、Web API、队列、Azure 函数和数据缓存。
Microsoft Entra ID
在货运跟踪门户中,用户可以通过输入跟踪编号来跟踪其购买的货物。 不过,普通用户可以注册为成员以访问高级功能,例如交付及时性和其他统计信息。 我们开发了跟踪门户,用于将用户帐户存储在 Microsoft Entra ID 中。
默认情况下,Microsoft Entra ID 已设计为一个全球性的系统。 因此,它不易受到区域性故障的影响,我们无需修改系统的这一组件。
Azure Blob 存储
静态内容(如图像和视频)作为二进制大型对象 (Blob) 存储在 Azure 存储帐户中,并通过 Azure CDN 提供给用户。
在原有设计中,由于选择使用本地冗余存储 (LRS),因此存储帐户包含在单个区域中。 使用 LRS 时,仅在单个数据中心内复制数据。 因此在此配置下,如果出现区域性中断,存储帐户将不可用。 用户仍可使用 CDN 已缓存的任何静态内容。
这同样适用于区域冗余存储 (ZRS)。 在此配置下,尽管数据会复制到其他数据中心,但所有这些数据中心仍位于同一区域。 在此配置下,区域性中断也会影响存储帐户。
在设计中,我们严重依赖 CDN 配置来缓存静态内容。 在中断期间,用户可能会请求尚未存在于 CDN 缓存中的静态文件。 此请求将导致无法显示图形或视频。
选择异地冗余存储选项时,可通过将存储帐户复制到多个区域来消除这种可能性。 只读复制选项还可用于防止在区域性服务中断期间添加静态内容。
需要启用异地冗余时,有两个选项可供选择。 这些选项是读取访问异地冗余存储 (RA-GRS) 和读取访问异地区域冗余存储 (RA-GZRS)。 选择取决于预算以及所需的运行时间百分比。
Azure 应用服务和 Azure 函数应用
货运跟踪门户实现两项 Azure 应用服务。 第一项应用服务托管一个 Web 应用,它实现面向用户的 Web 界面;第二项托管一个 Web API,移动应用使用它来跟踪货运数据。 所有后台任务都作为 Azure 函数应用运行。
在原有设计中,每个 Azure 应用服务都局限于单个 Azure 区域。 我们将在次要区域(美国西部)创建第二个应用服务,并在其中部署 Web 项目以支持新的多区域体系结构。 我们将配置 Azure Front Door 优先路由模式,以便在主要区域不可用时将请求发送到次要区域。
为确保故障转移尽可能顺畅,请确保 Web 应用程序不会在内存中存储任何会话状态信息。 我们将更改网站,以确保不出现数据丢失。 例如,如果代码在内存中存储了用户的货物列表,则发生故障转移时,此列表将丢失。
如果不存储会话状态,则处理每个 Web 请求时不会影响另一个。 如果在用户会话过程中发生故障转移,则用户应不会察觉到故障转移。
我们将对 Azure 函数应用进行类似的更改。 我们将在次要区域中创建单独的 Azure 函数实例,并向其部署与运行于主要区域中的代码相同的自定义代码。
重要
将更新部署到应用服务或函数应用服务中的自定义代码时,请记住将其分发到应用服务的所有实例。 如果想要自动执行此过程,Azure DevOps 提供了可以帮助你的工具。
Azure 存储队列
在原有单区域体系结构中,我们使用了 Azure 存储帐户中的队列来管理应用服务与函数应用之间的通信。 当 Web 应用或 Web API 需要运行后台任务时,它会在队列中放置一条包含所有必需信息的消息。 函数应用会监视队列中的新消息,并通过对数据存储运行必要的查询来执行后台任务。
以这种方式使用队列时,可以有序地管理 Web 请求中的高需求。 当有多个后台任务要运行时,队列可能加长,但任务不会被删除。 它们会一直处于队列中,直到得到处理。 函数应用将逐一处理队列中的任务,并在需求降低时缩减队列大小。 如果需求一直持续,我们将增加函数应用的实例数。
对于多区域版本的货运跟踪门户,必须确保发生故障转移时不会丢失队列项。 队列在 Azure 存储中定义,可以使用冗余选项进行异地复制。
请记住,由于队列支持读写操作,因此无法使用读取访问冗余选项。 应用服务必须将项添加到队列中,且函数应用必须从队列中删除已完成的项。 请改用异地冗余存储 (GRS) 或地理区域冗余存储 (GZRS)。
Azure Redis 缓存
我们使用 Azure Redis 缓存来最大程度地提高数据存储的性能。 Redis 会缓存应用程序从数据库请求数据时生成的所有查询结果。 任何对类似数据的进一步查询都不需要数据库查询,而是从 Redis 缓存进行提取。
对于多区域体系结构,我们将在主要区域和备用区域中创建 Redis 缓存实例。 请记住,发生故障转移时,备用区域中的 Redis 缓存很可能为空。 空缓存不会导致任何错误,但在数据填充新缓存时,性能可能会暂时下降。