

# 测试和调试 Lambda@Edge 函数
<a name="lambda-edge-testing-debugging"></a>

请务必单独测试 Lambda@Edge 函数代码以确保它完成预期的任务，并进行集成测试以确保该函数在 CloudFront 中正常工作。

在集成测试期间或在部署函数后，您可能需要调试 CloudFront 错误，例如，HTTP 5xx 错误。错误可能是从 Lambda 函数返回的无效响应、触发该函数时的执行错误，或者由于 Lambda 服务限制执行而产生的错误。本主题中的部分使用相同的策略以确定问题是哪种故障类型，并采取相同的措施以纠正该问题。

**注意**  
如果在纠正错误时查看 CloudWatch 日志文件或指标，请注意它们显示或存储在位置最接近执行函数的 AWS 区域。因此，如果您的网站或 Web 应用程序用户位于英国，并且 Lambda 函数与您的分配关联，您必须更改区域以查看伦敦 AWS 区域的 CloudWatch 指标或日志文件。有关更多信息，请参阅 [确定 Lambda@Edge 区域](#lambda-edge-testing-debugging-determine-region)。

**Topics**
+ [

## 测试 Lambda@Edge 函数
](#lambda-edge-testing-debugging-test-function)
+ [

## 识别 CloudFront 中的 Lambda@Edge 函数错误
](#lambda-edge-identifying-function-errors)
+ [

## 排查 Lambda@Edge 函数响应无效问题（验证错误）
](#lambda-edge-testing-debugging-troubleshooting-invalid-responses)
+ [

## 排查 Lambda@Edge 函数执行错误
](#lambda-edge-testing-debugging-execution-errors)
+ [

## 确定 Lambda@Edge 区域
](#lambda-edge-testing-debugging-determine-region)
+ [

## 确定您的账户是否将日志推送到 CloudWatch
](#lambda-edge-testing-debugging-cloudwatch-logs-enabled)

## 测试 Lambda@Edge 函数
<a name="lambda-edge-testing-debugging-test-function"></a>

可以使用两个步骤测试 Lambda 函数：单独测试和集成测试。

**测试单独功能**  
在将 Lambda 函数添加到 CloudFront 之前，请确保先使用 Lambda 控制台中的测试功能或其他方法测试该功能。有关在 Lambda 控制台中进行测试的更多信息，请参阅《AWS Lambda 开发人员指南》**中的[使用控制台调用 Lambda 函数](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html#get-started-invoke-manually)。

**在 CloudFront 中测试您的函数的运行情况**  
请务必完成集成测试，其中，您的函数与一个分配关联并根据 CloudFront 事件运行。确保为正确的事件触发函数，并为 CloudFront 返回有效且正确的响应。例如，确保事件结构正确无误，仅包含有效标头等等。  
在 Lambda 控制台上重复对函数进行集成测试时，请在修改代码或更改调用函数的 CloudFront 触发器时参阅 Lambda@Edge 教程中的步骤。例如，确保您使用带编号的函数版本，如本教程中的以下步骤所述：[第 4 步：添加 CloudFront 触发器来运行函数](lambda-edge-how-it-works-tutorial.md#lambda-edge-how-it-works-tutorial-add-trigger)。  
在进行更改和部署时，请注意需要几分钟的时间以在所有区域中复制更新的函数和 CloudFront 触发器。这通常需要几分钟，但最长需要 15 分钟。  
您可以转到 CloudFront 控制台并查看您的分配，确认复制是否完成。  

**检查您的复制是否已完成部署**

1. 通过以下网址打开 CloudFront 控制台：[https://console.aws.amazon.com/cloudfront/v4/home](https://console.aws.amazon.com/cloudfront/v4/home)。

1. 选择分配名称。

1. 查看分配的状态是否已从**正在进行**恢复为**已部署**，这意味着已复制函数。然后，按照下一节中的步骤验证函数是否正常工作。
请注意，控制台中的测试只会验证函数的逻辑，而不会应用特定于 Lambda@Edge 的任何服务限额（以前称为限制）。

## 识别 CloudFront 中的 Lambda@Edge 函数错误
<a name="lambda-edge-identifying-function-errors"></a>

在确认您的函数逻辑正常工作后，在 CloudFront 中运行函数时，您可能仍会看到 HTTP 5xx 错误。可能返回 HTTP 5xx 错误的原因有很多，其中包括 Lambda 函数错误或 CloudFront 中的其他问题。
+ 如果您使用 Lambda@Edge 函数，则可以在 CloudFront 控制台中使用图表帮助跟踪导致错误的原因，然后进行修复。例如，您可以查看是 CloudFront 还是 Lambda 函数导致了 HTTP 5xx 错误，然后，对于特定函数，您可以查看相关的日志文件来调查问题。
+ 要对 CloudFront 中的常规 HTTP 错误进行问题排查，请参阅以下主题中的问题排查步骤：[对 CloudFront 中的错误响应状态代码进行故障排除](troubleshooting-response-errors.md)。

### 是什么原因导致 CloudFront 中的 Lambda@Edge 函数错误
<a name="lambda-edge-testing-debugging-function-errors"></a>

Lambda 函数导致 HTTP 5xx 错误可能有很多原因，您应采取的故障排除措施取决于错误类型。错误可以归类如下：

**Lambda 函数执行错误。**  
如果由于函数中存在未处理的异常或代码中存在错误，使得 CloudFront 没有从 Lambda 中收到响应，则会导致执行错误。例如，如果代码包含回调（错误）。

**向 CloudFront 返回无效的 Lambda 函数响应**  
函数运行后，CloudFront 会收到来自 Lambda 的响应。如果响应的对象结构不符合 [Lambda@Edge 事件结构](lambda-event-structure.md)，或响应包含无效的标头或其他无效的字段，则会返回错误。

**由于 Lambda 服务配额（以前称为限制），CloudFront 中的执行受到限制**  
Lambda 服务限制每个区域中的执行次数，并在超过配额时返回错误。有关更多信息，请参阅 [有关 Lambda@Edge 的配额](cloudfront-limits.md#limits-lambda-at-edge)。

### 如何确定故障类型
<a name="lambda-edge-testing-debugging-failure-type"></a>

为了帮助您在调试和处理以解决 CloudFront 返回的错误时确定重点，确定 CloudFront 返回 HTTP 错误的原因会有所帮助。要开始使用，您可以使用 AWS 管理控制台 上 CloudFront 控制台的**监控**部分中提供的图表。有关在 CloudFront 控制台的**监控**部分中查看图表的更多信息，请参阅[使用 Amazon CloudWatch 监控 CloudFront 指标](monitoring-using-cloudwatch.md)。

在您希望跟踪错误是由源还是由 Lambda 函数返回时，以及在错误源自 Lambda 函数时需要缩小问题类型的范围时，下列图表会非常有用。

**错误率图表**  
在**概览**选项卡上，您可以看到各个分配的一个图表是**错误率**图表。此图表显示相对于传入到您分配的请求总数，错误率的百分比。图表显示总错误率、4xx 错误总数、5xx 错误总数以及来自 Lambda 函数的 5xx 错误总数。根据错误类型和卷，您可以采取措施来调查和排查造成错误的原因。  

![\[CloudFront 分配的错误率图表\]](http://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/images/Distribution-error-rate-pct-full.png)

+ 如果您看到 Lambda 错误，可以通过查看函数返回的特定类型错误来进一步进行调查。**Lambda@Edge 错误**选项卡包含按类型分类函数错误的图表，帮助您确定特定函数的问题。
+ 如果您看到 CloudFront 错误，可以进行故障排查和处理来修复原始错误，或者更改 CloudFront 配置。有关更多信息，请参阅 [对 CloudFront 中的错误响应状态代码进行故障排除](troubleshooting-response-errors.md)。

**执行错误和无效函数响应图表**  
**Lambda@Edge 错误**选项卡包含针对特定分配按类型对 Lambda@Edge 错误进行分类的图表。例如，一个图表按 AWS 区域显示所有执行错误。  
要更轻松地解决问题，您可以通过按区域打开并检查特定函数的日志，来查找特定问题。  

**按区域查看特定函数的日志文件**

1. 在 **Lambda@Edge 错误**选项卡上，在**关联的 Lambda@Edge 函数**下，选择函数名称，然后选择**查看指标**。

1. 接下来，在包含函数名称的页面上，在右上角选择**查看函数日志**，然后选择一个区域。

   例如，如果您在**错误**图表中看到美国西部（俄勒冈州）区域存在问题，请从下拉列表中选择该区域。这将打开 Amazon CloudWatch 控制台。

1. 在该区域的 CloudWatch 控制台中，在**日志流**下，选择一个日志流以查看该函数的事件。
此外，阅读本章中的下列部分，了解有关问题排查和修复错误的更多建议。

**限制图表**  
**Lambda@Edge 错误**选项卡还包括一个**限制**图表。有时候，在您达到了区域并发限制（以前称为限制）时，Lambda 服务会按区域限制函数调用。如果您发现超出限制错误，则您的函数已达到 Lambda 服务对在区域中执行所施加的配额。有关更多信息（包括如何请求提高配额），请参阅[有关 Lambda@Edge 的配额](cloudfront-limits.md#limits-lambda-at-edge)。  

![\[Lambda@Edge 函数执行的限制图表。\]](http://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/images/Lambda-throttles-page.png)


有关如何在排查 HTTP 错误时使用此信息的示例，请参阅[调试 AWS 上的内容分发的四个步骤](https://aws.amazon.com/blogs/networking-and-content-delivery/four-steps-for-debugging-your-content-delivery-on-aws/)。

## 排查 Lambda@Edge 函数响应无效问题（验证错误）
<a name="lambda-edge-testing-debugging-troubleshooting-invalid-responses"></a>

如果您发现问题是 Lambda 验证错误，则表示您的 Lambda 函数向 CloudFront 返回无效的响应。请按照此部分中的指导采取措施以检查您的函数，并确保您的响应符合 CloudFront 要求。

CloudFront 通过两种方式验证来自 Lambda 函数的响应：
+ **Lambda 响应必须符合所需的对象结构。**不正确的对象结构示例包括：无法解析 JSON，缺少必填字段以及在响应中包含无效的对象。有关更多信息，请参阅[Lambda@Edge 事件结构](lambda-event-structure.md)。
+ **响应只能包含有效的对象值。**如果响应包含有效的对象，但具有不支持的值，则会出现错误。示例包括：添加或更新列入黑名单的标头或只读标头（请参阅 [边缘函数的限制](edge-functions-restrictions.md)），超出最大正文大小（请参阅 Lambda [错误](lambda-generating-http-responses.md#lambda-generating-http-responses-errors) 主题中的*生成的响应大小的限制*）和无效的字符或值（请参阅 [Lambda@Edge 事件结构](lambda-event-structure.md)）。

在 Lambda 向 CloudFront 返回无效的响应时，将在日志文件中写入错误消息，CloudFront 将这些日志文件推送到执行 Lambda 函数所在的区域中的 CloudWatch。这是在具有无效的响应时将日志文件发送到 CloudWatch 的默认行为。不过，如果在发布该功能之前将 Lambda 函数与 CloudFront 相关联，则可能不会为您的函数启用该功能。有关更多信息，请参阅本主题后面的*确定您的账户是否将日志推送到 CloudWatch*。

CloudFront 将日志文件推送到与您函数的执行位置对应的区域（在与您的分配关联的日志组中）。日志组具有以下格式：`/aws/cloudfront/LambdaEdge/DistributionId`，其中 *DistributionId* 是您的分配的 ID。要确定可以找到 CloudWatch 日志文件的区域，请参阅本主题后面的*确定 Lambda@Edge 区域*。

如果可再现该错误，您可以创建一个导致该错误的新请求，然后在失败的 CloudFront 响应（`X-Amz-Cf-Id` 标头）中找到请求 ID 以在日志文件中找到单个故障。日志文件条目包含可帮助您确定返回错误的原因的信息，并且还会列出相应的 Lambda 请求 ID，以便您可以在单个请求的上下文中分析根本原因。

如果错误是间歇性的，您可以使用 CloudFront 访问日志查找失败请求的请求 ID，然后在 CloudWatch 日志中搜索相应的错误消息。有关更多信息，请参阅上一节*确定故障类型*。

## 排查 Lambda@Edge 函数执行错误
<a name="lambda-edge-testing-debugging-execution-errors"></a>

如果问题是 Lambda 执行错误，为 Lambda 函数创建日志记录语句以将消息写入到 CloudWatch 日志文件可能是非常有用的，从而在 CloudFront 中监视函数的执行情况并确定它是否正常工作。然后，您可以在 CloudWatch 日志文件中搜索这些语句，以验证您的函数是否正常工作。

**注意**  
即使您尚未更改 Lambda@Edge 函数，对该 Lambda 函数执行环境的更新也可能会影响它并可能返回执行错误。有关测试和迁移到更高版本的信息，请参阅[对 AWS Lambda 和 AWS Lambda@Edge 执行环境的近期更新](https://aws.amazon.com/blogs/compute/upcoming-updates-to-the-aws-lambda-execution-environment/)。

## 确定 Lambda@Edge 区域
<a name="lambda-edge-testing-debugging-determine-region"></a>

要查看 Lambda@Edge 函数接收流量的区域，请在 AWS 管理控制台上的 CloudFront 控制台中查看此函数的指标。指标针对各个 AWS 区域显示。在同一页上，您可以选择一个区域并查看该区域的日志文件，从而调查问题。您必须查看相应 AWS 区域中的 CloudWatch 日志文件，以查看在 CloudFront 执行 Lambda 函数时创建的日志文件。

有关在 CloudFront 控制台的**监控**部分中查看图表的更多信息，请参阅[使用 Amazon CloudWatch 监控 CloudFront 指标](monitoring-using-cloudwatch.md)。

## 确定您的账户是否将日志推送到 CloudWatch
<a name="lambda-edge-testing-debugging-cloudwatch-logs-enabled"></a>

默认情况下，CloudFront 为无效的 Lambda 函数响应启用日志记录，并使用[Lambda@Edge 的服务相关角色](lambda-edge-permissions.md#using-service-linked-roles-lambda-edge)之一将日志文件推送到 CloudWatch。如果在发布无效的 Lambda 函数响应日志功能之前将 Lambda@Edge 函数添加到 CloudFront，下次更新 Lambda@Edge 配置时，将启用日志记录，例如，通过添加 CloudFront 触发器。

您可以执行以下操作，以验证是否为您的账户启用将日志文件推送到 CloudWatch 的功能：
+ **检查日志是否显示在 CloudWatch 中** – 确保您查看了执行 Lambda@Edge 函数的区域。有关更多信息，请参阅 [确定 Lambda@Edge 区域](#lambda-edge-testing-debugging-determine-region)。
+ **在 IAM 中确定您的账户中是否存在相关的服务相关角色** – 您的账户中必须有 IAM 角色 `AWSServiceRoleForCloudFrontLogger`。有关该角色的更多信息，请参阅[Lambda@Edge 的服务相关角色](lambda-edge-permissions.md#using-service-linked-roles-lambda-edge)。