

# 排查失败金丝雀的问题
<a name="CloudWatch_Synthetics_Canaries_Troubleshoot"></a>

如果您的金丝雀失败，请检查以下内容以排查问题。

 **一般故障排除** 
+ 使用金丝雀详细信息页面查找更多信息。在 CloudWatch 控制台中，选择导航窗格中的**金丝雀**，然后选择金丝雀的名称以打开金丝雀详细信息页面。在**可用性**选项卡上，选中 **SuccessPercent** 指标以查看问题是经常性问题还是间歇性问题。

  仍在 **Availability（可用性）**选项卡上时，选择失败的数据点以查看该失败运行的屏幕截图、日志和步骤报告（如可用）。

  如果步骤报告可用（因为步骤是脚本的一部分），请检查以查明失败的步骤，并查看相关屏幕截图以查看客户看到的问题。

  您还可以检查 HAR 文件以了解是否有一个或多个请求失败。您可以使用日志对失败的请求和错误进行深入分析。最后，您可以将这些构件与成功金丝雀运行中的构件进行比较，以查明问题。

  预设情况下，CloudWatch Synthetics 会捕获 UI 金丝雀中每个步骤的屏幕截图。但您的脚本可能会配置为禁用屏幕截图。在调试期间，您可能希望再次启用屏幕截图。同样，对于 API 金丝雀，您可能希望在调试过程中查看 HTTP 请求和响应标头和响应体。有关如何将此数据包括在报告中，请参阅 [executeHttpStep(stepName, requestOptions, [callback], [stepConfig])](CloudWatch_Synthetics_Canaries_Library_Nodejs.md#CloudWatch_Synthetics_Library_executeHttpStep)。
+ 如果您最近对应用程序做出了部署，请执行回滚操作，然后稍后进行调试。
+ 手动连接到端点，看看是否会重现相同问题。

**Topics**
+ [金丝雀在 Lambda 环境更新后发生故障](#Troubleshoot_upgradeLambda)
+ [我的金丝雀被 Amazon WAF 阻止了](#Canary_Blocked_WAF)
+ [等待元素出现](#CloudWatch_Synthetics_Canaries_Troubleshoot_waiting)
+ [节点不可见或不是用于 page.click() 的 HTMLElement](#CloudWatch_Synthetics_Canaries_Troubleshoot_notvisible)
+ [无法将构件上载到 S3，“异常：无法获取 S3 存储桶位置：访问被拒绝”](#CloudWatch_Synthetics_Canaries_Troubleshoot_noupload)
+ [“错误：协议错误 (Runtime.callFunctionOn)：目标已关闭。”](#CloudWatch_Synthetics_Canaries_Troubleshoot_protocolError)
+ [“金丝雀失败。错误：无数据点 – 金丝雀显示超时”错误](#CloudWatch_Synthetics_Canaries_Troubleshoot_nodatapoint)
+ [尝试访问内部端点](#CloudWatch_Synthetics_Canaries_Troubleshoot_internalendpoint)
+ [金丝雀运行时版本升级和降级问题](#CloudWatch_Synthetics_Canaries_Troubleshoot_upgradeissues)
+ [跨域请求共享 (CORS) 问题](#CloudWatch_Synthetics_Canaries_CORS)
+ [金丝雀争用情况问题](#CloudWatch_Synthetics_Canaries_RaceCondition)
+ [排查 VPC 上金丝雀的问题](#CloudWatch_Synthetics_Canaries_VPC_troubleshoot)
+ [对自动重试金丝雀进行问题排查](#CloudWatch_Synthetics_Canaries_autoretry)

## 金丝雀在 Lambda 环境更新后发生故障
<a name="Troubleshoot_upgradeLambda"></a>

CloudWatch Synthetics 金丝雀在您的账户中作为 Lambda 函数实施。这些 Lambda 函数需要定期更新 Lambda 运行时系统，其中包括安全更新、错误修复和其他改进。Lambda 致力于提供与现有函数向后兼容的运行时系统更新。但是，与软件修补一样，在极少数情况下，运行时更新会对现有函数产生负面影响。如果您认为自己的金丝雀受到 Lambda 运行时系统更新的影响，则可以使用 Lambda 运行时系统管理手动模式（在支持的区域中）来临时回滚 Lambda 运行时系统版本。这样，可以使金丝雀函数保持正常运行并最大限度地减少中断，从而在返回到最新的运行时系统版本之前有时间解决不兼容问题。

如果您的金丝雀在 Lambda 运行时系统更新后出现故障，最好的解决方案是升级到最新的 Synthetics 运行时系统之一。有关最新运行时系统的更多信息，请参阅 [Synthetics 运行时版本](CloudWatch_Synthetics_Canaries_Library.md)。

作为替代解决方案，在提供 Lambda 运行时系统管理控件的区域中，您可以使用手动模式进行运行时系统管理控制，将金丝雀恢复到较旧的 Lambda 托管运行时系统。您可以按照以下各部分中的以下步骤使用 Amazon CLI 或通过 Lambda 控制台设置手动模式。

**警告**  
当您将运行时系统设置更改为手动模式时，您的 Lambda 函数在恢复到自动模式之前不会收到自动安全更新。在此期间，您的 Lambda 函数可能容易受到安全漏洞的影响。

 **先决条件** 
+ 安装 [jq](https://jqlang.github.io/jq/)
+ 安装最新版本的 Amazon CLI。有关更多信息，请参阅 [Amazon CLI 安装和更新说明](https://docs.amazonaws.cn/cli/latest/userguide/getting-started-install.html#getting-started-install-instructions)。

### 步骤 1：获取 Lambda 函数 ARN
<a name="UpgradeLambda_ObtainFunctionARN"></a>

运行以下命令，以从响应中检索 `EngineArn` 字段。此 `EngineArn` 是与金丝雀关联的 Lambda 函数的 ARN。您将在以下步骤中使用此 ARN。

```
aws synthetics get-canary --name my-canary | jq '.Canary.EngineArn'
```

`EngingArn` 的示例输出：

```
"arn:aws:lambda:us-west-2:123456789012:function:cwsyn-my-canary-dc5015c2-db17-4cb5-afb1-EXAMPLE991:8"
```

### 步骤 2：获取最后一个良好的 Lambda 运行时系统版本 ARN
<a name="UpgradeLambda_RuntimeARN"></a>

为了帮助了解您的金丝雀是否受到 Lambda 运行时系统更新的影响，请检查日志中 Lambda 运行时系统版本 ARN 更改的日期和时间是否与您看到金丝雀受到影响的日期和时间一致。如果两者不匹配，则可能不是 Lambda 运行时系统更新导致您的问题。

如果您的金丝雀受到 Lambda 运行时系统更新的影响，则必须识别之前正在使用的有效 Lambda 运行时系统版本的 ARN。按照[识别运行时系统版本更改](https://docs.amazonaws.cn/lambda/latest/dg/runtimes-update.html#runtime-management-identify.html)中的说明查找先前的运行时系统的 ARN。记录运行时系统版本 ARN，然后继续执行步骤 3，以设置运行时系统管理配置。

如果您的金丝雀尚未受到 Lambda 环境更新的影响，则可以查找您当前正在使用的 Lambda 运行时系统版本的 ARN。运行以下命令，以从响应中检索 Lambda 函数的 `RuntimeVersionArn`。

```
aws lambda get-function-configuration \
--function-name "arn:aws:lambda:us-west-2:123456789012:function:cwsyn-my-canary-dc5015c2-db17-4cb5-afb1-EXAMPLE991:8" | jq '.RuntimeVersionConfig.RuntimeVersionArn'
```

`RuntimeVersionArn` 的示例输出：

```
"arn:aws:lambda:us-west-2::runtime:EXAMPLE647b82f490a45d7ddd96b557b916a30128d9dcab5f4972911ec0f"
```

### 步骤 3：更新 Lambda 运行时系统管理配置
<a name="UpgradeLambda_Update"></a>

您可以使用 Amazon CLI 或 Lambda 控制台来更新运行时系统管理配置。

 **要设置 Lambda 运行时系统管理配置手动模式，请使用 Amazon CLI** 

输入以下命令，以将 Lambda 函数的运行时系统管理更改为手动模式。请务必使用您在步骤 1 中找到的值，将 *function-name* 和 *qualifier* 分别替换为 Lambda 函数 ARN 和 Lambda 函数版本号。另外，将 *runtime-version-arn* 替换为您在步骤 2 中找到的版本 ARN。

```
aws lambda put-runtime-management-config \
    --function-name "arn:aws:lambda:us-west-2:123456789012:function:cwsyn-my-canary-dc5015c2-db17-4cb5-afb1-EXAMPLE991" \
    --qualifier 8 \
    --update-runtime-on "Manual" \
    --runtime-version-arn "arn:aws:lambda:us-west-2::runtime:a993d90ea43647b82f490a45d7ddd96b557b916a30128d9dcab5f4972911ec0f"
```

**要使用 Lambda 控制台将金丝雀更改为手动模式**

1. 通过 [https://console.aws.amazon.com/lambda/](https://console.amazonaws.cn/lambda/) 打开 Amazon Lambda 控制台。

1. 选择**版本**选项卡，选择与您的 ARN 对应的版本号链接，然后选择**代码**选项卡。

1. 向下滚动到**运行时系统设置**，展开**运行时系统管理配置**，然后复制**运行时系统版本 ARN**。  
![\[显示屏幕的运行时设置部分，并显示运行时版本 ARN 在此部分中的显示位置。\]](http://docs.amazonaws.cn/AmazonCloudWatch/latest/monitoring/images/SyntheticsManual1.png)

1. 选择**编辑运行时管理配置**，选择**手动**，将之前复制的运行时版本 ARN 粘贴到**运行时版本 ARN** 字段中。然后选择**保存**。  
![\[显示运行时管理配置屏幕，并显示要将之前复制的运行时版本 ARN 粘贴到其中的位置。\]](http://docs.amazonaws.cn/AmazonCloudWatch/latest/monitoring/images/SyntheticsManual2.png)

## 我的金丝雀被 Amazon WAF 阻止了
<a name="Canary_Blocked_WAF"></a>

要允许金丝雀流量通过 Amazon WAF，请创建一个 Amazon WAF 字符串匹配条件，该条件允许您指定的自定义字符串。有关更多信息，请参阅 Amazon WAF 文档中的[使用字符串匹配条件](https://docs.amazonaws.cn/waf/latest/developerguide/classic-web-acl-string-conditions.html)。

强烈建议您使用自己的自定义用户代理字符串，而不是使用默认值。这可以更好地控制 Amazon WAF 筛选并提高安全性。

要设置自定义用户代理字符串，请执行以下操作：
+ 对于 Playwright 运行时，您可以使用 Synthetics 配置文件附加 Amazon WAF 批准的自定义用户代理字符串。有关更多信息，请参阅 [CloudWatch Synthetics 配置](Synthetics_WritingCanary_Nodejs_Playwright.md#Synthetics_canary_configure_Playwright_script)。
+ 对于 Puppeteer 或 Selenium 运行时，您可以使用支持的库函数添加自定义用户代理字符串。有关 Puppeteer 运行时，请参阅 [async addUserAgent(page, userAgentString);](CloudWatch_Synthetics_Canaries_Library_Nodejs.md#CloudWatch_Synthetics_Library_addUserAgent)。有关 Selenium 运行时，请参阅 [add\$1user\$1agent(user\$1agent\$1str)](CloudWatch_Synthetics_Canaries_Library_Python.md#CloudWatch_Synthetics_Library_add_user_agent)。

## 等待元素出现
<a name="CloudWatch_Synthetics_Canaries_Troubleshoot_waiting"></a>

分析日志和屏幕截图后，如果您发现脚本正在等待某个元素出现在屏幕上并超时，请检查相关的屏幕截图以查看该元素是否出现在页面上。验证 `xpath` 以确保该元素的准确性。

对于与 Puppeteer 相关的问题，请参阅 [Puppeteer 的 GitHub 页面](https://github.com/puppeteer/puppeteer/issues)或 Internet 论坛。

## 节点不可见或不是用于 page.click() 的 HTMLElement
<a name="CloudWatch_Synthetics_Canaries_Troubleshoot_notvisible"></a>

如果节点不可见或不是用于 `page.click()` 的 `HTMLElement`，请首先验证您正在用于单击元素的 `xpath`。另外，如果您的元素位于屏幕底部，请调整视区。预设情况下，CloudWatch Synthetics 采用的视区为 1920 \$1 1080。您可以在启动浏览器时或使用 Puppeteer 函数 `page.setViewport` 另行设置视区。

## 无法将构件上载到 S3，“异常：无法获取 S3 存储桶位置：访问被拒绝”
<a name="CloudWatch_Synthetics_Canaries_Troubleshoot_noupload"></a>

如果您的金丝雀因 Amazon S3 错误而失败，CloudWatch Synthetics 无法上传屏幕截图、日志或因权限问题为金丝雀创建的报告。请检查以下事项：
+ 检查金丝雀的 IAM 角色是否具有 `s3:ListAllMyBuckets` 权限、对正确的 Amazon S3 存储桶的 `s3:GetBucketLocation` 权限，以及对金丝雀存储其构件的存储桶的 `s3:PutObject` 权限。如果金丝雀执行可视化监控，该角色还需要存储桶的 ` s3:GetObject` 权限。如果 Canary 部署在具有 VPC 端点的 VPC 中，则 Amazon VPC S3 网关端点策略也需要相同权限。
+  如果金丝雀使用 Amazon KMS 客户托管式密钥而不是标准 Amazon 托管式密钥（默认）来加密，金丝雀的 IAM 角色可能没有使用该密钥加密或解密的权限。有关更多信息，请参阅 [加密金丝雀构件](CloudWatch_Synthetics_artifact_encryption.md)。
+ 您的存储桶策略可能不允许金丝雀使用的加密机制。例如，如果您的存储桶策略要求使用特定的加密机制或 KMS 密钥，则必须为金丝雀选择相同的加密模式。

如果金丝雀执行可视化监控，请参阅 [使用可视化监控时更新构件位置和加密](CloudWatch_Synthetics_artifact_encryption.md#CloudWatch_Synthetics_artifact_encryption_visual) 了解更多信息。

## “错误：协议错误 (Runtime.callFunctionOn)：目标已关闭。”
<a name="CloudWatch_Synthetics_Canaries_Troubleshoot_protocolError"></a>

如果在页面或浏览器关闭后还有一些网络请求，则会出现此错误。您可能忘记了等待异步操作。执行脚本后，CloudWatch Synthetics 会关闭浏览器。关闭浏览器后执行任何异步操作可能会导致 `target closed error` 错误。

## “金丝雀失败。错误：无数据点 – 金丝雀显示超时”错误
<a name="CloudWatch_Synthetics_Canaries_Troubleshoot_nodatapoint"></a>

此错误指金丝雀运行超过了超时时间。金丝雀执行在 CloudWatch Synthetics 发布成功率 CloudWatch 指标或更新构件（如 HAR 文件、日志和屏幕截图）前已经停止。如果超时时间太低，您可以将其提高。

预设情况下，金丝雀的超时值等于其频率。您可以手动将超时值调整为小于或等于金丝雀频率。如果金丝雀频率较低，则必须增加频率以提高超时时间。在使用 CloudWatch Synthetics 控制台创建或更新金丝雀时，您可以在 **Schedule（计划）**下调整频率和超时值。

请确保金丝雀超时值不要短于 15 秒钟，以预留 Lambda 冷启动以及启动金丝雀工具的时间。

发生此错误时，无法在 CloudWatch Synthetics 控制台中查看金丝雀构件。您可以使用 CloudWatch Logs 查看金丝雀的日志。

**使用 CloudWatch Logs 查看金丝雀的日志**

1. 通过 [https://console.aws.amazon.com/cloudwatch/](https://console.amazonaws.cn/cloudwatch/) 打开 CloudWatch 控制台。

1. 在左侧导航窗格中，选择 **Log groups（日志组）**。

1. 在筛选器框中键入金丝雀名称来查找日志组。金丝雀的日志组名称为 **/aws/lambda/cwsyn-*canaryName*-randomId**。

## 尝试访问内部端点
<a name="CloudWatch_Synthetics_Canaries_Troubleshoot_internalendpoint"></a>

如果希望您的金丝雀访问内部网络上的端点，我们建议您将 CloudWatch Synthetics 设置为使用 VPC。有关更多信息，请参阅 [在 VPC 上运行金丝雀](CloudWatch_Synthetics_Canaries_VPC.md)。

## 金丝雀运行时版本升级和降级问题
<a name="CloudWatch_Synthetics_Canaries_Troubleshoot_upgradeissues"></a>

如果您最近将金丝雀的运行时版本从 `syn-1.0` 升级到更高版本，则可能是跨域请求共享 (CORS) 问题。有关更多信息，请参阅 [跨域请求共享 (CORS) 问题](#CloudWatch_Synthetics_Canaries_CORS)。

如果您最近将金丝雀运行时版本降级到较旧版本，请检查以确保您正在使用的 CloudWatch Synthetics 函数在您降级到的旧运行时版本中可用。例如，`executeHttpStep` 函数可用于 `syn-nodejs-2.2` 或更高版本的运行时。要检查函数的可用性，请参阅 [编写金丝雀脚本](CloudWatch_Synthetics_Canaries_WritingCanary.md)。

**注意**  
当您计划升级或降级金丝雀的运行时系统版本时，我们建议您首先克隆金丝雀并更新克隆金丝雀中的运行时系统版本。在验证了使用新运行时版本的克隆金丝雀正常运行后，您可以更新原始金丝雀的运行时版本并删除克隆金丝雀。

## 跨域请求共享 (CORS) 问题
<a name="CloudWatch_Synthetics_Canaries_CORS"></a>

在 UI 金丝雀中，如果某些网络请求失败并显示 `403` 或 ` net::ERR_FAILED` 错误，请检查金丝雀是否启用了活动跟踪，并使用 Puppeteer 函数 `page.setExtraHTTPHeaders` 添加标头。若是如此，则网络请求失败可能是由跨域请求共享 (CORS) 限制所致。您可以通过禁用活动跟踪或删除额外的 HTTP 标头来确认是否属于这种情况。

 **为什么会发生这种情况？** 

在使用活动跟踪时，会向所有传出请求添加额外的标头以跟踪调用。通过使用 Puppeteer 的 `page.setExtraHTTPHeaders` 来添加跟踪标头或添加额外标头的方式来修改请求标头，会导致对 XMLHttpRequest (XHR) 请求进行 CORS 检查。

如果您不想禁用活动跟踪或删除额外标头，则可以更新 Web 应用程序以允许跨域访问，也可以在脚本中启动 Chrome 浏览器时使用 `disable-web-security` 标志来禁用 Web 安全。

您可以覆盖 CloudWatch Synthetics 所用的启动参数，并通过使用 CloudWatch Synthetics 启动函数传递其他 ` disable-web-security` 标记参数。有关更多信息，请参阅 [可用于使用 Puppeteer 的 Node.js Canary 脚本的库函数](CloudWatch_Synthetics_Canaries_Library_Nodejs.md)。

**注意**  
如果您使用的是 `syn-nodejs-2.1` 或更高运行时版本，则可以覆盖 CloudWatch Synthetics 所用的启动参数。

## 金丝雀争用情况问题
<a name="CloudWatch_Synthetics_Canaries_RaceCondition"></a>

为了在使用 CloudWatch Synthetics 时获得最佳体验，请确保为金丝雀编写的代码具有幂等性。否则，在极少数情况下，当金丝雀在不同的运行中与相同资源交互时，Canary 运行可能会遇到争用情况。

## 排查 VPC 上金丝雀的问题
<a name="CloudWatch_Synthetics_Canaries_VPC_troubleshoot"></a>

如果您在创建或更新使用 VPC 的金丝雀后遇到问题，以下其中一部分可能会帮助您解决问题。

### 新的金丝雀处于错误状态或无法更新金丝雀
<a name="CloudWatch_Synthetics_Canaries_VPC_troubleshoot_errorstate"></a>

如果您创建要在 VPC 上运行的金丝雀，并且它立即进入错误状态，或者您无法更新金丝雀以在 VPC 上运行，则金丝雀的角色可能没有正确的权限。要在 VPC 上运行，金丝雀必须具有权限 ` ec2:CreateNetworkInterface`、`ec2:DescribeNetworkInterfaces` 和 ` ec2:DeleteNetworkInterface`。这些权限包含在 ` AWSLambdaVPCAccessExecutionRole` 托管策略中。有关更多信息，请参阅[执行角色和用户权限](https://docs.amazonaws.cn/lambda/latest/dg/configuration-vpc.html#vpc-permissions)。

如果在创建金丝雀时发生此问题，必须删除此金丝雀，然后创建一个新的金丝雀。如果您使用 CloudWatch 控制台创建新金丝雀，请在 **Access Permissions（访问权限）**下选择 **Create a new role（创建新角色）**。此时将创建一个新角色，该角色包含运行金丝雀所需的全部权限。

如果在更新金丝雀时发生此问题，可以再次更新金丝雀并提供具有必要权限的新角色。

### “未返回测试结果”错误
<a name="CloudWatch_Synthetics_Canaries_VPC_troubleshoot_noresult"></a>

如果金丝雀显示“未返回测试结果”错误，以下问题之一可能是导致这个问题的原因：
+ 如果您的 VPC 不具有 Internet 访问权限，则必须使用 VPC 终端节点授予金丝雀对 CloudWatch 和 Amazon S3 的访问权限。您必须在 VPC 中启用 **DNS 解析**和 **DNS 主机名**选项，才能正确解析这些终端节点地址。有关更多信息，请参阅 [将 DNS 与 VPC 配合使用](https://docs.amazonaws.cn/vpc/latest/userguide/vpc-dns.html) 以及 [将 CloudWatch 和 CloudWatch Synthetics 与接口 VPC 端点配合使用](https://docs.amazonaws.cn/AmazonCloudWatch/latest/monitoring/cloudwatch-and-interface-VPC.html)。
+ 金丝雀必须在 VPC 内的私有子网中运行。要检查是否存在此问题，请在 VPC 控制台中打开**子网**页面。检查您在配置金丝雀时选择的子网。如果它们具有通往互联网网关 (**igw-**) 的路径，则不是私有子网。

要帮助您解决这些问题，请参阅金丝雀日志。

**要查看来自金丝雀的日志事件，请执行以下操作：**

1. 通过 [https://console.aws.amazon.com/cloudwatch/](https://console.amazonaws.cn/cloudwatch/) 打开 CloudWatch 控制台。

1. 在导航窗格中，选择 **Log groups（日志组）**。

1. 选择金丝雀日志组的名称。日志组名称以 ` /aws/lambda/cwsyn-canary-name` 开头。

## 对自动重试金丝雀进行问题排查
<a name="CloudWatch_Synthetics_Canaries_autoretry"></a>

要了解金丝雀失败的原因或分析特定的失败尝试，请按照以下问题排查步骤进行操作。

1. 通过 [https://console.aws.amazon.com/cloudwatch/](https://console.amazonaws.cn/cloudwatch/) 打开 CloudWatch 控制台。

1. 在导航窗格中，选择 **Application Signals**、**Synthetics 金丝雀**。

1. 选择**金丝雀**。

1. 在**可用性**选项卡下，您可以通过以下任一方式检查运行详细信息：
   + 在金丝雀运行图表上选择特定点
   + 在**问题**下选择一条记录。请注意，重试尝试会经过标记并与其计划运行共享时间戳

   您可以在**步骤**、**屏幕截图**、**日志**、**HAR 文件**或**跟踪**（如果启用了主动跟踪）下查看其他信息。

1. 在**金丝雀构件和 Amazon S3 位置**下，您可以访问构件并通过可用链接导航到 Amazon S3 文件夹或存储桶。

1. **金丝雀运行**图表使用不同颜色的点来表示不同的状态：
   + 蓝色点 – 表示计划运行成功，一致值为 100%
   + 红色点 – 显示失败的计划运行和所有重试，标记为 0%
   + 橙色点 – 显示 0% 或 100%。0% 表示在上一次尝试失败后正在进行重试，100% 表示重试后成功了