你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

任务关键型工作负载的运行状况建模

监视应用程序和基础结构是任何基础结构部署的重要组成部分。 对于任务关键型工作负载,监视是部署的关键部分。 监视 Azure 资源的应用程序运行状况和关键指标有助于了解环境是否按预期工作。

若要全面了解这些指标并评估工作负载的总体运行状况,需要全面了解所监视的所有数据。 运行状况模型可以通过显示工作负载运行状况的明确指示(而不是原始指标)来帮助评估总体运行状况。 状态通常显示为“交通灯”指示器,如红色、绿色或黄色。 以清晰指标表示运行状况模型使操作员能够直观地了解工作负载的总体运行状况,并对出现的问题做出快速响应。

运行状况建模可以扩展到任务关键型部署的以下操作任务:

  • 应用程序运行状况服务 - 计算群集上的应用程序组件,提供 API 来确定标记的运行状况。

  • 监视 - 性能和应用程序计数器的集合,用于评估应用程序和基础结构的运行状况和性能。

  • 警报 - 基础结构和应用程序中出现问题或中断的可操作警报。

  • 故障分析 - 对任何故障的细分和分析,包括根本原因的文档。

这些任务构成了任务关键型基础结构的综合运行状况模型。 开发运行状况模型可以而且应该是任何任务关键型部署的详尽且不可或缺的一部分。

有关详细信息,请参阅 Azure 上任务关键型工作负载的运行状况建模和可观测性

应用程序运行状况服务

应用程序运行状况服务 (HealthService) 是与目录服务 (CatalogService) 和后台处理器 (BackgroundProcessor) 一起驻留在计算群集中的应用程序组件。 HealthService 为 Azure Front Door 提供 REST API 用于调用,以确定标记的运行状况。 HealthService 是一个复杂的组件,除了反映自己的状态,它还反映了依赖项的状态。

计算群集关闭时,运行状况服务不会响应。 当服务启动并运行时,会针对基础结构中的以下组件执行定期检查:

  • 尝试针对 Azure Cosmos DB 执行查询。

  • 尝试向事件中心发送消息。 消息被后台工作器筛选掉。

  • 在存储帐户中查找状态文件。 此文件可用于关闭区域,即使其他检查仍在正常运行。 此文件可用于与其他进程通信。 例如,如果出于维护目的要空出标记,则可以删除该文件,以强制进入不正常状态并重新路由流量。

  • 查询运行状况模型,以确定所有操作指标是否在预先确定的阈值内。 当运行状况模型指示标记不正常时,即使 HealthService 执行的其他测试成功返回,也不应将流量路由到标记。 运行状况模型更全面地考虑了运行状况。

所有运行状况检查结果都会缓存在内存中,缓存时间为可配置的秒数,默认为 10。 此操作确实可能会在检测中断时增加一点延迟,但它确保并非每个 HealthService 查询都需要后端调用,从而减少群集和下游服务的负载。

此缓存模式很重要,因为使用 Azure Front Door 等全局路由器时,HealthService 查询的数量会显著增加:每个 Azure 数据中心中提供请求的每个边缘节点都将调用运行状况服务以确定其后端连接是否正常工作。 缓存结果可减少运行状况检查生成的额外群集负载。

配置

HealthService 和 CatalogService 具有组件之间通用的配置设置,但以下设置为 HealthService 专用:

设置
HealthServiceCacheDurationSeconds 控制内存缓存的过期时间(以秒为单位)。
HealthServiceStorageConnectionString 存储帐户的连接字符串,其中应存在状态文件。
HealthServiceBlobContainerName 存储容器,其中应存在状态文件。
HealthServiceBlobName 状态文件的名称 - 运行状况检查将查找此文件。
HealthServiceOverallTimeoutSeconds 整个检查的超时 - 默认值为 3 秒。 如果检查未在此间隔内完成,服务将报告运行不正常。

实现

所有检查都是以异步并行方式执行的。 如果任一检查失败,整个标记将视为不可用。

使用标准的非分布式 ASP.NET Core MemoryCache 将检查结果缓存在内存中。 缓存过期由 SysConfig.HealthServiceCacheDurationSeconds 控制,默认设为 10 秒。

注意

SysConfig.HealthServiceCacheDurationSeconds 配置设置减少了运行状况检查生成的额外负载,因为并非所有请求都会导致对依赖服务的下游调用。

下表详细说明了基础结构中组件的运行状况检查:

组件 运行状况检查
存储帐户 Blob Blob 检查目前有两个用途:
1. 测试是否可以访问 Blob 存储。 标记中的其他组件会使用该存储帐户,因此该帐户被视为关键资源。
2. 通过删除状态文件手动“关闭”区域。
做出一个设计决策,即检查仅在指定 Blob 容器中查看是否存在状态文件。 未处理文件的内容。 可以设置一个更复杂的系统,用于读取文件的内容,并根据文件的内容返回不同的状态。
内容示例包括“正常”、“不正常”和“维护”。
删除状态文件将禁用标记。 请确保部署应用程序后存在运行状况文件。 缺少运行状况文件将导致服务始终使用“不正常”进行响应。 Front Door 不会将后端识别为可用。
该文件由 Terraform 创建,应在基础结构部署后存在。
事件中心 事件中心运行状况报告由 EventHubProducerService 处理。 如果该服务能够向事件中心发送新消息,则它会报告运行正常。 对于筛选,此消息已添加了一个标识属性:
HEALTHCHECK=TRUE
此消息在接收端被忽略。 AlwaysOn.BackgroundProcessor.EventHubProcessorService.ProcessEventHandlerAsync() 配置设置检查 HEALTHCHECK 属性。
Azure Cosmos DB Azure Cosmos DB 运行状况报告由 CosmosDbService 处理,如果符合以下情况,则报告正常:
1。 能够连接到 Azure Cosmos DB 数据库并执行查询。
2. 能够将测试文档写入数据库。
测试文档设置的生存时间较短,Azure Cosmos DB 会自动将其删除。
HealthService 执行两个单独的探测。 如果 Azure Cosmos DB 处于读取正常工作而写入不正常工作的状态,则两个探测可确保触发警报。

Azure Cosmos DB 查询

对于只读查询,将使用以下查询,该查询不会提取任何数据,并且对总体负载没有太大影响:

SELECT GetCurrentDateTime ()

写入查询创建具有最少内容的虚拟 ItemRating

var testRating = new ItemRating()
{
    Id = Guid.NewGuid(),
    CatalogItemId = Guid.NewGuid(), // Create some random (=non-existing) item id
    CreationDate = DateTime.UtcNow,
    Rating = 1,
    TimeToLive = 10 // will be auto-deleted after 10sec
};

await AddNewRatingAsync(testRating);

监视

Azure Log Analytics 用作所有应用程序和基础结构组件的日志和指标的中央存储。 Azure Application Insights 用于所有应用程序监视数据。 基础结构中的每个标记都有一个专用的 Log Analytics 工作区和 Application Insights 实例。 单独的 Log Analytics 工作区用于全局共享的资源,例如 Front Door 和 Azure Cosmos DB。

所有标记的生存期都较短,并不断替换为每个新版本。 每个标记的 Log Analytics 工作区部署为单独的监视资源组中的全局资源,作为标记 Log Analytics 资源。 这些资源不会共享标记的生命周期。

有关详细信息,请参阅用于相关分析的统一数据接收器

监视:数据源

  • 诊断设置:所有用于 Azure Mission-Critical 的 Azure 服务都配置为将所有诊断数据(包括日志和指标)发送到特定于部署(全局或标记)的 Log Analytics 工作区。 此过程作为 Terraform 部署的一部分自动发生。 将自动识别新选项,并将其添加为 terraform apply 的一部分。

  • Kubernetes 监视:诊断设置用于将 Azure Kubernetes 服务 (AKS) 日志和指标发送到 Log Analytics。 AKS 配置为使用容器见解。 容器见解通过 AKS 群集中每个节点上的 Kubernetes DaemonSet 部署 OMSAgentForLinus。 OMSAgentForLinux 能够从 Kubernetes 群集中收集额外日志和指标,并发送到其相应的 Log Analytics 工作区。 这些额外的日志和指标包含有关 pod、部署、服务和整体群集运行状况的更细粒度的数据。 若要从各种组件(例如 ingress-nginx、cert-manager 和部署到任务关键型工作负载旁边的 Kubernetes 的其他组件)中获取更多见解,可以使用 Prometheus 抓取。 Prometheus 抓取将 OMSAgentForLinux 配置为从群集内的各个终结点抓取 Prometheus 指标。

  • Application Insights 遥测:Application Insights 用于从应用程序收集遥测数据。 该代码已经过检测,可以使用 Application Insights SDK 收集有关应用程序性能的数据。 收集关键信息,例如生成的状态代码和依赖项调用的持续时间以及未经处理的异常的计数器。 此信息在运行状况模型中使用,可用于警报和故障排除。

监视:Application Insights 可用性测试

若要从外部角度监视各个标记和整体解决方案的可用性,请在两个位置设置 Application Insights 可用性测试

  • 区域可用性测试:这些测试在区域 Application Insights 实例中设置,用于监视标记的可用性。 这些测试直接面向群集和标记的静态存储帐户。 若要直接调用群集的入口点,请求需要携带正确的 Front Door ID 标头,否则会被入口控制器拒绝。

  • 全局可用性测试:这些测试在全局 Application Insights 实例中设置,用于通过 ping Front Door 监视整体解决方案的可用性。 使用了两个测试:一个用于测试针对 CatalogService 的 API 调用,一个用于测试网站的主页。

监视:查询

Azure Mission-Critical 使用不同的Kusto 查询语言 (KQL) 查询将自定义查询实现为从 Log Analytics 检索数据的函数。 这些查询作为单个文件存储在代码存储库中,分别用于全局部署和标记部署。 作为每个基础结构管道运行的一部分,这些查询通过 Terraform 自动导入和应用。

此方法将查询逻辑与可视化层分开。 Log Analytics 查询直接从代码调用,例如从 HealthService API 调用。 另一个示例是从可视化工具调用,例如 Azure 仪表板、监视工作簿或 Grafana。

监视:可视化

为了可视化 Log Analytics 运行状况查询的结果,我们在参考实现中使用了 Grafana。 Grafana 用于显示 Log Analytics 查询的结果,本身不包含任何逻辑。 Grafana 堆栈不是解决方案部署生命周期的一部分,而是单独发布的。

有关详细信息,请参阅可视化

警报

警报是整体操作策略的重要组成部分。 主动监视(例如仪表板的使用)应与警报一起使用,以便立即引起对问题的关注。

通过向操作员发出运行状况更改的警报(降级/黄色状态或不正常/红色状态),这些警报构成了运行状况模型的扩展。 通过将警报设置为运行状况模型的根节点,操作员可以立即意识到任何业务级别对解决方案状态的影响:毕竟,如果任何基础用户流或资源报告黄色或红色指标,此根节点将变为黄色或红色。 操作员可以关注运行状况模型可视化,以便进行故障排除。

有关详细信息,请参阅自动化事件响应

故障分析

编写故障分析主要是理论规划练习。 此理论练习应用作作为连续验证过程一部分的自动化故障注入的输入。 通过模拟此处定义的故障模式,我们可以验证解决方案对这些故障的复原能力,以确保不会导致中断。

下表列出了 Azure Mission-Critical 参考实现的各个组件的示例故障案例。

服务 风险 影响/缓解措施/注释 中断
Microsoft Entra ID Microsoft Entra ID 变得不可用。 目前没有可能的缓解措施。 多区域方法不会缓解任何中断,因为它是一项全局服务。 此服务是硬依赖项。 Microsoft Entra ID 用于控制平面操作,例如创建新的 AKS 节点、从 ACR 拉取容器映像或在 Pod 启动时访问密钥保管库。 预期正在运行的现有组件应该能够在 Microsoft Entra ID 遇到问题时继续运行。 新 Pod 或 AKS 节点可能无法生成。 在此期间需要进行大规模操作,这可能会导致用户体验下降,并可能导致中断。 部分
Azure DNS Azure DNS 变得不可用,DNS 解析失败。 如果 Azure DNS 变得不可用,则用户请求的 DNS 解析以及应用程序的不同组件之间的 DNS 解析可能会失败。 目前没有针对这种情况的可能缓解措施。 多区域方法不会缓解任何中断,因为它是一项全局服务。 Azure DNS 是硬依赖项。 外部 DNS 服务作为备份不起作用,因为使用的所有 PaaS 组件都依赖于 Azure DNS。 不可选择通过切换到 IP 绕过 DNS。 Azure 服务没有静态、有保证的 IP 地址。 完整
Front Door 常规 Front Door 中断。 如果 Front Door 完全关闭,则没有缓解措施。 此服务是硬依赖项。
Front Door 路由/前端/后端配置错误。 部署时可能由于配置不匹配而发生这种情况。 应在测试阶段捕获到。 使用 DNS 的前端配置特定于每个环境。 缓解措施:回滚到以前的配置应修复大多数问题。 由于 Front Door 中的更改需要几分钟才能部署,因此会导致中断。 完整
Front Door 已删除托管 TLS/SSL 证书。 部署时可能由于配置不匹配而发生这种情况。 应在测试阶段捕获到。 从技术上讲,站点仍然正常工作,但 TLS/SSL 证书错误将阻止用户进行访问。 缓解措施:重新颁发证书可能需要大约 20 分钟,以及修复并重新运行管道。 完整
Azure Cosmos DB 数据库/集合已重命名。 部署时可能由于配置不匹配而发生这种情况 - Terraform 会覆盖整个数据库,这可能会导致数据丢失。 可以使用数据库/集合级别锁来防止数据丢失。 应用程序将无法访问任何数据。 需要更新应用配置并重启 Pod。
Azure Cosmos DB 区域中断 Azure Mission-Critical 启用了多区域写入。 如果读取或写入失败,客户端会重试当前操作。 所有将来的操作将按照优先顺序永久路由到下一个区域。 如果首选项列表有一个条目(或为空),但该帐户还有其他可用区域,则该帐户将会路由到帐户列表中的下一个区域。
Azure Cosmos DB 由于缺少 RU,因此存在广泛的限制。 根据在 Front Door 级别使用的 RU 数和负载均衡情况,某些标记可以在 Azure Cosmos DB 利用率上热运行,而其他标记可以提供更多请求。 缓解措施:更好的负载分布或更多 RU。
Azure Cosmos DB 分区已满 Azure Cosmos DB 逻辑分区大小限制为 20 GB。 如果容器中分区键的数据达到此大小,则其他写入请求将失败,并显示错误“分区键达到最大大小”。 部分(已禁用 DB 写入)
Azure 容器注册表 区域中断 容器注册表使用流量管理器在副本区域之间进行故障转移。 任何请求都应自动重新路由到另一个区域。 最坏的情况是,在发生 DNS 故障转移时,AKS 节点无法在几分钟内拉取 Docker 映像。
Azure 容器注册表 已删除映像 无法拉取任何映像。 此中断应仅影响新生成/重新启动的节点。 现有节点应缓存映像。 **缓解措施:如果检测到快速重新运行最新的生成管道,则应将映像重新引入注册表。
Azure 容器注册表 限制 限制会延迟横向扩展操作,从而导致性能暂时下降。 缓解措施:Azure Mission-Critical 使用高级 SKU,每分钟提供 10k 次读取操作。 容器镜像经过优化,层数很少。 ImagePullPolicy 设置为 IfNotPresent 以首先使用本地缓存的版本。 注释:拉取容器映像包含多个读取操作,具体取决于层数。 每分钟的读取操作数是有限的,取决于 ACR SKU 大小
Azure Kubernetes 服务 群集升级失败 AKS 节点升级应跨标记在不同时间进行。 如果一个升级失败,其他群集不应受到影响。 群集升级应以滚动方式跨节点进行部署,以防止所有节点变得不可用。
Azure Kubernetes 服务 提供请求时,应用程序 Pod 会终止。 这可能导致最终用户面临错误和不良的用户体验。 缓解措施:默认情况下,Kubernetes 以常规方式移除 Pod。 首先从服务中移除 Pod,工作负载会收到一个带有宽限期的 SIGTERM,以在终止之前完成打开的请求并写入数据。 应用程序代码需要了解 SIGTERM,如果工作负载需要更长的时间才能关闭,则可能需要调整宽限期。
Azure Kubernetes 服务 计算区域中不可用的容量以添加更多节点。 纵向扩展/横向扩展操作将失败,但不应影响现有节点及其操作。 理想情况下,流量应自动转移到其他区域进行负载均衡。
Azure Kubernetes 服务 订阅达到 CPU 核心配额以添加新节点。 纵向扩展/横向扩展操作将失败,但不应影响现有节点及其操作。 理想情况下,流量应自动转移到其他区域进行负载均衡。
Azure Kubernetes 服务 无法颁发/续订 Let’s Encrypt TLS/SSL 证书。 群集应向 Front Door 报告不正常,流量应转移到其他标记。 缓解措施:调查问题/续订失败的根本原因。
Azure Kubernetes 服务 资源请求/限制配置不正确时,Pod 的 CPU 使用率可能达到 100% 并导致请求失败。 应用程序重试机制应能够恢复失败的请求。 重试可能会导致请求持续时间更长,而不会向客户端显示错误。 负载过量最终会导致故障。 否(如果负载不过量)
Azure Kubernetes 服务 第三方容器映像/注册表不可用 某些组件(例如 cert-manager 和 ingress-nginx)需要从外部容器注册表(出站流量)下载容器映像和 helm 图表。 如果这些存储库或映像中的一个或多个不可用,则新节点(尚未缓存映像)上的新实例可能无法启动。 可能的缓解措施:在某些情况下,可将第 3 方容器映像导入每个解决方案的容器注册表中。 这增加了额外的复杂性,应仔细规划和实施。 部分(在缩放和更新/升级操作期间)
事件中心 无法将消息发送到事件中心 标记变得不可用于写入操作。 运行状况服务应自动检测此情况,并停止轮换标记。
事件中心 BackgroundProcessor 无法读取消息 消息将排队。 消息不应丢失,因为它们被持久保存。 目前,运行状况服务未涵盖此故障。 应在工作器上设置监视/警报,以检测读取消息时出现的错误。 缓解措施:在问题得到修复之前,应手动禁用标记。
存储帐户 事件中心检查点的工作器无法使用存储帐户 标记不会处理来自事件中心的消息。 HealthService 也使用存储帐户。 预计 HealthService 应检测到存储方面的问题,并且标记应停止轮换。 预计标记中的其他服务将同时受到影响。
存储帐户 静态网站遇到问题。 如果静态网站的服务遇到问题,则 Front Door 应检测到此故障。 不会将流量发送到此存储帐户。 Front Door 的缓存也可以缓解此问题。
密钥保管库 密钥保管库不可用于 GetSecret 操作。 在新 Pod 启动时,AKS CSI 驱动程序将从密钥保管库提取所有机密并失败。 Pod 将无法启动。 当前每 5 分钟自动更新一次。 更新将失败。 错误应显示在 kubectl describe pod 中,但 Pod 会一直正常工作。
密钥保管库 密钥保管库不可用于 GetSecretSetSecret 操作。 无法执行新部署。 目前,即使只有一个区域受到影响,此故障也可能导致整个部署管道停止。
密钥保管库 密钥保管库限制 密钥保管库限制为每 10 秒 1000 次操作。 由于机密自动更新,如果标记中有许多(数千)个 Pod,则理论上可以达到此限制。 可能的缓解措施:进一步降低更新频率或完全关闭更新。
应用程序 配置错误 注入到应用的连接字符串或机密不正确。 应通过自动部署(管道自动处理配置)和蓝绿更新推出来缓解。
应用程序 过期凭据(标记资源) 例如,如果事件中心 SAS 令牌或存储帐户密钥已更改,但没有在密钥保管库中进行相应更新以供 Pod 使用,则相应的应用程序组件将失败。 然后,此故障会影响运行状况服务,并且标记应自动停止轮换。 缓解措施:对所有支持基于 Microsoft Entra ID 的身份验证的服务使用该身份验证。 AKS 要求 Pod 使用 Microsoft Entra Workload ID(预览版)进行身份验证。 参考实现中考虑了 Pod 标识的使用。 发现 Pod 标识目前不够稳定,并决定不用于当前的参考体系结构。 Pod 标识可能是将来的解决方案。
应用程序 过期凭据(全局共享资源) 例如,如果 Azure Cosmos DB API 密钥已更改,但没有在所有标记密钥保管库中进行相应的更新以供 Pod 使用,则相应的应用程序组件将失败。 此故障将同时关闭所有标记,并导致工作负载范围的中断。 有关使用 Microsoft Entra 身份验证解决密钥和机密需求的可能方法,请参阅上一项。 完全
虚拟网络 子网 IP 地址空间已用尽 如果子网上的 IP 地址空间用尽,则不会执行任何横向扩展操作,例如创建新的 AKS 节点或 Pod。 这不会导致中断,但可能会降低性能并影响用户体验。 缓解措施:增加 IP 空间(如果可能)。 如果这种做法不可行,则可以增加每个节点的资源(更大的 VM SKU)或每个 Pod 的资源(更多 CPU/内存),以便每个 Pod 可以处理更多流量,从而减少横向扩展的需求。

后续步骤

部署参考实现,以便全面了解此体系结构中使用的资源及其配置。