排查功能标志方面的问题

本指南介绍了诊断和解决 App Lifecycle Manager 功能标志常见问题的步骤。

SDK 和运行时评估

OpenFeature API 经过精心设计,可确保标志评估调用不会抛出未处理的异常,而是在发生评估错误时返回默认值。

症状:标志返回安全的默认值

如果标志服务无法访问、提供程序不可用或标志配置错误,SDK 会返回代码中提供的必需默认值。

解决方法:

  1. 验证 OpenFeature 提供程序与 saasconfig.googleapis.com 端点之间的连接。
  2. 检查是否存在身份验证错误。确保应用的运行时服务账号具有 roles/saasconfig.viewer 角色。
  3. 验证 FLAGD_SOURCE_PROVIDER_ID 是否正确。

问题:评估结果不符合预期

如果标志未返回预期变体,请执行以下操作:

解决方法:

  1. 请检查您的 CEL 条件和评估上下文。
  2. 如果在条件检查期间上下文中缺少必需属性,评估引擎会跳过该特定规则。
  3. 如果在基于百分比的分配期间缺少属性,则评估会返回 INVALID_CONTEXT。

排查以应用为中心的模板同步和控制台发布问题

如果您使用 Application Design Center 复合模板和 Google Cloud 控制台开始使用功能标志,请按照以下步骤解决模板同步和发布问题。

症状:连接 App Design Center 复合模板后,未创建单元种类

如果您在连接复合模板后,SaaS 产品中的单元种类标签页仍然为空,请执行以下操作:

解决方法:

  1. 在将复合模板导入 SaaS 产品/服务之前,请验证每个嵌入式标准应用模板和父级复合应用模板是否已添加到 Application Design Center 的目录中。
  2. 验证 App Lifecycle Manager 服务代理 (service-PROJECT_NUMBER@gcp-sa-saasservicemgmt.) 在您的项目中是否具有 roles/saasservicemgmt.serviceAgent 角色。
  3. 在 Google Cloud 控制台中查看 SaaS 产品详情页面,或运行 gcloud beta app-lifecycle-manager saas describe SAAS_OFFERING_ID --location=global 以检查模板同步状态。

替换以下内容:

  • PROJECT_NUMBER:您的 Google Cloud 项目编号。
  • SAAS_OFFERING_ID:您的 SaaS 产品/服务的 ID。

症状:在控制台中发布标志后,根据标准模板创建的单元未更新

如果标志发布在 Google Cloud 控制台中完成,但根据标准模板创建的单元未收到更新后的标志配置,请执行以下操作:

解决方法:

  1. 验证该单元是否属于目标单元类型、是否位于发布范围内的区域,以及是否与发布类型上配置的任何 unitFilter 匹配。
  2. 确认应用中的 FLAGD_SOURCE_PROVIDER_ID 与单元的完整功能标志配置资源路径 (projects/PROJECT_ID/locations/LOCATION/featureFlagsConfigs/UNIT_ID) 匹配。

替换以下内容:

  • PROJECT_ID:您的 Google Cloud 项目 ID。
  • LOCATION:单元所在的区域。
  • UNIT_ID:单位的 ID。

监控发布

监控功能标志发布涉及验证编排状态(发布是否已完成?)和应用运行状况(二进制文件是否获取了标志?)。

发布编排状态

系统会实时监控操作的成功率。

自动暂停

为防止错误配置影响整个机群,如果某个位置的故障率超过了发布类型(errorBudget.allowedCount 或 errorBudget.allowedPercentage,例如每个位置 10% 的阈值)上配置的错误预算,系统会自动暂停发布。

查看摘要统计信息

使用 describe 命令查看汇总失败次数,并确定发布是 PAUSED 还是 FAILED。

gcloud beta app-lifecycle-manager rollouts describe ROLLOUT_ID --location=global

过滤失败的单元更新

确认存在故障后,您必须找到未更新的具体单元。使用此过滤条件可仅找出特定区域中失败的标志更新:

gcloud beta app-lifecycle-manager unit-operations list \
    --location=LOCATION \
    --filter="state:UNIT_OPERATION_STATE_FAILED AND flag_update:*"

诊断根本原因

对于每个失败的操作,您可以在 conditions 字段(message 和 reason)和 errorCategory 中检索由执行引擎提供的详细出错提示(或检查发布资源上的 stateMessage)。

gcloud beta app-lifecycle-manager unit-operations describe OPERATION_ID --location=LOCATION

替换以下内容:

  • ROLLOUT_ID:发布作业的 ID。
  • LOCATION:单元操作的区域。
  • OPERATION_ID:单元操作的 ID。

单元缺少配置

本部分介绍了单元固定如何阻止单元接收功能标志配置,以及如何恢复单元。

了解单元固定

固定操作会将单元冻结在当前版本,从而防止其通过任何自动或手动发布进行更新。在固定期结束或手动取消固定之前,固定单元会明确排除在发布操作之外。

缺少固定单元的配置

在功能标志发布期间,如果某个单元被固定,就会出现严重问题。固定会阻止所有更新,这意味着设备会跳过接收其配置所需的 FlagUpdate 操作。

症状:在单元取消固定并升级到需要功能标志的二进制文件后,应用无法初始化或进入无限重试循环,导致就绪探测失败和容器持续重启。

根本原因:在单元被固定的情况下,发布更新了父级单元种类资源的 defaultFlagRevisions 字段,但固定单元跳过了 FlagUpdate 操作,未收到有效配置。

诊断命令

使用以下命令检查失败的标志更新操作和单元状态。

1. 列出失败的标记操作

如需查找未更新的单元,请按 UNIT_OPERATION_STATE_FAILED 状态和 flag_update 类型过滤单元操作。

gcloud beta app-lifecycle-manager unit-operations list \
    --location="LOCATION" \
    --filter="state:UNIT_OPERATION_STATE_FAILED AND flag_update:*"

2. 专门过滤失败的标志发布

如需在整个舰队或特定单元中找出失败的标志更新,请为 UNIT_OPERATION_STATE_FAILED 状态添加条件。

gcloud beta app-lifecycle-manager unit-operations list \
    --location="LOCATION" \
    --filter="unit:UNIT_ID AND state:UNIT_OPERATION_STATE_FAILED AND flag_update:*"

3. 检查失败原因

使用 describe 命令检查 conditions 字段(message 和 reason)以及 errorCategory。

gcloud beta app-lifecycle-manager unit-operations describe "OPERATION_ID" --location="LOCATION"

4. 检查设备状况

您也可以直接查看单元的当前状态。如果标志发布失败或上次操作导致错误,则单元的 conditions 列表中会包含一个带有 type: TYPE_OPERATION_ERROR 的条目。

gcloud beta app-lifecycle-manager units describe "UNIT_ID" --location="LOCATION"

替换以下内容:

  • LOCATION:单元或单元操作所在的区域。
  • UNIT_ID:单元的 ID。
  • OPERATION_ID:单元操作的 ID。

手动缓解措施

如需恢复因错过标志更新而导致状态异常的固定单元,请应用其父级单元种类的默认标志修订版本。

应用单元种类默认标志修订版本

如果某个单元因在一个或多个发布阶段被固定而缺少配置,您可以通过手动将该单元重置为其单元类型中定义的当前基准来恢复该单元。

  1. 取消固定单元(如果已固定):

    gcloud beta app-lifecycle-manager units update "UNIT_ID" \
        --location="LOCATION" \
        --maintenance-pinned-until-time=""
    
  2. 从父级单元种类检索默认修订版本:

    gcloud beta app-lifecycle-manager unit-kinds describe "UNIT_KIND_ID" \
        --location="LOCATION" \
        --format="value(defaultFlagRevisions.join(','))"
    
  3. 创建包含这些修订版本的新 FlagRelease:

    gcloud beta app-lifecycle-manager flags releases create "recovery-release-1" \
        --location="LOCATION" \
        --unit-kind="UNIT_KIND_ID" \
        --revisions="REVISIONS"
    
  4. 手动启动 FlagUpdate 单元操作以应用恢复版本:

    gcloud beta app-lifecycle-manager unit-operations create "recovery-op" \
        --unit="UNIT_ID" \
        --flag-update="projects/PROJECT_ID/locations/LOCATION/flagReleases/recovery-release-1" \
        --location="LOCATION"
    

替换以下内容:

  • UNIT_ID:要恢复的单元的 ID。
  • LOCATION:单元所在的区域。
  • UNIT_KIND_ID:父级单位种类的 ID。
  • REVISIONS:第 2 步中返回的默认标志修订版本资源名称的英文逗号分隔列表。
  • PROJECT_ID:您的 Google Cloud 项目 ID。