Amazon CloudFront 部署小指南(四)- CloudFront Function 基础与诊断

JavaScript
内容分发网络 CDN
Amazon CloudFront
Amazon Lambda
0
0
## **内容简介** 本文适用于希望使用 [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) Functions 提升 [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) 边缘计算能力的用户,旨在帮助您更好的进行 CloudFront Functions 的开发、调试、测试、部署等工作。 首先我们会对 CloudFront Function 做个简单的介绍,然后分为七个步骤为您讲述如何创建一个带有 CloudFront Function 处理能力的测试环境,并开展一些相关的调试工作。 **步骤一**:准备基于[部署小指南(二)](https://dev.amazoncloud.cn/column/article/64b513651da59862086bbddd)的整体架构 **步骤二**:创建一个 CloudFront Function 函数 **步骤三**:发布函数并关联 CloudFront 分配 **步骤四**:CloudFront 日志输出及查询 **步骤五**:使用 Response Header 来完成快速调试 **步骤六**:查看 CloudFront Functions 计算利用率 **步骤七**:CloudFront Extension 中的 CFF 应用 通过本指南,您将学会如何使用 CloudFront,快速构建一个内容分发网络,并展示分发效果。 ### **CloudFront Function 和 Amazon Lambda\\@Edge 的简单的介绍** 使用 [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail),您可以编写自己的代码来处理 HTTP 请求和响应。代码在您的用户附近运行以最大限度的减少延迟,并且您无需管理服务器或其他基础设施。您可编写代码来操纵流经 CloudFront 的请求和响应、执行基本身份验证和授权、在边缘生成 HTTP 响应等。您编写并附加到 CloudFront 分配的代码称为边缘函数。CloudFront 目前提供了两种编写和管理边缘函数的方法: * CloudFront Functions – 借助 CloudFront Functions,您可以使用 JavaScript 编写轻量级函数,以实现大规模、对延迟敏感的 CDN 自定义处理。CloudFront Functions 运行时环境提供亚毫秒级启动时间,可立即扩展以每秒处理数百万个请求,并且高度安全。CloudFront Functions 是 CloudFront 的原生功能,这意味着您可以完全在 CloudFront 中构建、测试和部署代码。 * Lambda\@Edge – Lambda\@Edge 是 Amazon Lambda 的扩展,它为复杂功能和完整的应用程序逻辑提供强大而灵活的计算,更接近您的查看者,并且高度安全。Lambda\@Edge 函数在 js 或 Python 运行时环境中运行。您将它们发布到单个 Amazon 区域,但当您将函数与 CloudFront 分配相关联时,Lambda\@Edge 会自动在全球范围内复制您的代码。 有关 CloudFront Functions 和 Lambda\@Edge 的区别以及选择可以参阅 CloudFront 文档: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/edge-functions.html?trk=cndc-detail 本文会致力于介绍 CloudFront Functions,Lambda\@Edge 相关的会在后续的 CloudFront 部署小指南系列里做深入讲解。 ### **如何开始 CloudFront Functions 的开发** CloudFront Functions 目前仅支持 JavaScript 作为开发语言,运行时环境符合 ECMAScript(ES)版本 5.1,还支持 ES 版本 6 到 9 的一些功能,同时还提供一些不属于 ES 规范的非标准方法。具体细节可以参考JavaScript runtime features for CloudFront Functions。鉴于此,建议您使用 [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) Functions 控制台进行 CloudFront Function 的开发和测试。 您仅需用定义函数名称和说明即可快速创建一个 CloudFront Function。 ![image.png](https://dev-media.amazoncloud.cn/4b37461be87e4d51a6b1ee8b23955d71_image.png "image.png") 创建完成后,将会得到一个带有示例代码的 CloudFront Function,您可以在此进行代码的开发、测试和发布。在构建页面,可以对代码进行编辑(开发),同时也能看到目前线上部署的最新代码(实时标签)。 ![image.png](https://dev-media.amazoncloud.cn/6b0629573fb74d92bb82aa12cd94f034_image.png "image.png") CloudFront Function 以事件(Event)驱动,我们编写的 CloudFront Function 代码,可以关联在 CloudFront 的 viewer event 或者 response event 上。例如,当关联在 CloudFront viewer event 时,每一个送达 CloudFront 分发点,匹配关联 CFF 特定 behavior 的 Web 请求都会触发 Cloud Front Pop 节点的运行环境里的 CloudFront Function 代码,依照代码对请求做出修改。如修改访问的 uri 来根据不同的设备提供适配设备屏幕的网页。或者验证请求的合法性等轻量级的计算工作。把这些计算工作交给遍布全球的 PoP 点中成百上千的服务器。能够大大提高最终用户的网页访问速度。减小源站的计算压力。 在这里,每一个 Web 请求的事件都提供给 CloudFront Function 一个 Event 的数据结构(在调试中 Event 数据结构以 json 格式呈现)。CloudFront Function 对 Event 数据结构进行修改,并返回数据结构。即完成了 Web 请求定制修改的工作。 下面我们就着手搭建一个最小的 CloudFront Function 环境: **步骤一:** **准备基于部署小指南(二)的整体架构来进行部署过程的演示** 首先,让我们基于 [CloudFront 部署小指南(二)](https://dev.amazoncloud.cn/column/article/64b513651da59862086bbddd),搭建一个加速动静结合网站的 CloudFront 环境。在本文中,我们主要会用这个环境里动态网站的部分来完成调试。 在调试过程中,我们会主要使用/api 这个关闭缓存的 Behavior path 进行调试。利用 Echo-Sever 观察 CloudFront Function 带来的 Web 请求的改变。 **步骤二:** **创建一个 CloudFront Function 函数** 我们以将跨源资源共享(CORS)标头添加到响应为需求通过 CloudFront Functions 的方式实现。 下面是一段添加 CORS Header 以支持跨域访问的代码案例,如果 Access-Control-Allow-Origin CORS Header 不存在,则添加该值。 ```js function handler(event) { var response = event.response; var headers = response.headers; // If Access-Control-Allow-Origin CORS header is missing, add it. // Since JavaScript doesn't allow for hyphens in variable names, we use the dict["key"] notation. if (!headers['access-control-allow-origin']) { headers['access-control-allow-origin'] = {value: "*"}; console.log("Access-Control-Allow-Origin was missing, adding it now."); } return response; } ``` 将上面的代码片段复制到控制台编辑窗口后保存更改。 ![image.png](https://dev-media.amazoncloud.cn/50aa3a9cd9f2440c8158b906c330e1f6_image.png "image.png") 在开发过程中,可以通过测试页面对代码进行调试,该代码会在 viewer response 阶段影响响应标头,事件类型选择 viewer response,测试阶段选择 Development,然后执行测试,测试结果如下: ![image.png](https://dev-media.amazoncloud.cn/28c2be12757e458bb8b0e14490033617_image.png "image.png") 测试函数支持模拟请求和响应的 headers、cookies、query string。我们在响应 – 响应标头下添加标头信息进行测试: ![image.png](https://dev-media.amazoncloud.cn/71350df850d041e586f8cb7c03a27a0a_image.png "image.png") 获得的测试效果结果如下,可以看到如果响应中已经包含 access-control-allow-origin 响应头,则不会重复添加该值。 ![image.png](https://dev-media.amazoncloud.cn/5132df2693174b1d8e43d97ca52a2005_image.png "image.png") 至此,我们完成了示例代码的全覆盖测试。 **步骤三:** **发布函数并关联 CloudFront 分配** 在发布中点击添加关联,选择需要关联的 CloudFront 分配,事件类型选择 Viewer Response,缓存行为选择 /api/\*,点击添加关联。关联添加完成后即可点击上面的发布函数按钮,将代码分发到关联的 CloudFront 分配上。 ![image.png](https://dev-media.amazoncloud.cn/6801d33be3ac467fb5f3d9b3f4129269_image.png "image.png") 发布完成后,可以通过 curl 命令进行测试,我们看到响应头中已经包含了 CORS 标头信息。 ```js curl -i http://xxxx.cloudfront.net/api/test ``` ![image.png](https://dev-media.amazoncloud.cn/e1ce528e3eac4591933f1bee1749fe09_image.png "image.png") **步骤四:** **CloudFront 日志输出及查询** 上面的代码通过 Console.log 进行日志输出,生产环境下这些日志会自动发送到 CloudWatch Logs。需要注意的是,无论在哪个边缘站点运行该函数,CloudFront Functions 始终在美国东部(弗吉尼亚北部)区域( `us-east-1` )中创建日志流。日志组名称的格式为 `/aws/cloudfront/function/FunctionName` ,其中 `FunctionName` 是您在创建函数时为函数指定的名称。 进入 CloudWatch 控制台,将 Region 切换到美国东部(弗吉尼亚北部)区域( us-east-1 ),搜索 FunctionName 找到对应的日志组,选择对应时间的日志流即可查看日志信息。 ![image.png](https://dev-media.amazoncloud.cn/73e479bc65064b9ca012b1fc5807a88a_image.png "image.png") 注意:在发布到生产环境时,建议删除不必要的日志输出,以节约成本。 **步骤五:** **使用 Response Header 来完成快速调试** 有些场景我们需要将 CloudFront Function 发布后和源一起调试,点击发布函数并不会立刻应用到所有的边缘节点,需要一段时间来部署完成。我们可以通过在 Response Header 中添加版本标头的方式,来确定当前请求使用的是哪个版本的代码。每次更新代码的时候,我们只需要变更版本号即可。 在 CloudFront 中进行调试的时候,我们需要频繁的去到 CloudWatch 查看日志,但日志发送到 CloudWatch 中会有一定的延迟,需要在 CloudWatch 中不断刷新以查看日志是否更新。此时我们可以通过在 Response Header 中输出信息来协助调试,对于复杂的代码逻辑,我们可以在 console.log()的同时将关键信息放到 Response Header 中。 比如下面的代码,我们想查看 request header 中的 Host 标头,以及查看源端返回的 cache-control 设置,我们可以将其通过 console.log()进行打印,同时将其放到 Response Header 中输出。 ```js function handler(event) { var response = event.response; var headers = response.headers; // check host value in request var host = event.request.headers.host; if (host) { console.log("print host value in request header: " + host.value) headers['log-host'] = { value: host.value } } // Print the cache-control header var originalCacheControl = headers['cache-control'] if (originalCacheControl) { console.log("print original cache contorl value: " + originalCacheControl.value) headers['log-old-cache-control'] = { value: originalCacheControl.value } } else { headers['log-old-cache-control'] = { value: "undefined" } } // Set the cache-control header headers['cache-control'] = {value: 'public, max-age=63072000'}; // If Access-Control-Allow-Origin CORS header is missing, add it. // Since JavaScript doesn't allow for hyphens in variable names, we use the dict["key"] notation. if (!headers['access-control-allow-origin']) { headers['access-control-allow-origin'] = {value: "*"}; console.log("Access-Control-Allow-Origin was missing, adding it now."); } headers['function-version'] = { value: 'V04' } return response; } ``` 使用 curl 进行访问结果如下,在 response header 中,我们可以通过 function-version 标头确定当前执行代码的版本,通过 req-host 获取打印的日志信息,避免了到 CloudWatch 不断刷新等到日志的流程,大大提高效率。调试完成后切记注释或删除日志相关的代码。 ![image.png](https://dev-media.amazoncloud.cn/c85afd87b60d440ab04bade81bb53b59_image.png "image.png") 使用 response header 输出信息进行调试的时候,需要遵循 response header 的规范,value 必须是 string 类型,且只有 CloudFront Function 执行正常将 response 完整返回给客户端时才能看到相关信息。如果代码执行异常,中断的情况,则无法获得正常响应,此时无法通过 response header 查看调试信息,这种情况下 console.log()可以将异常中断前的日志都打印出来。我们在实际开发测试时可以结合使用。 **步骤六:** **查看 CloudFront Functions 计算利用率** **Compute utilization(计算利用率**)是函数运行所花费的时间占最大允许时间的百分比。例如,值为 35 表示函数在最大允许时间的 35% 内完成。如果函数持续超过最大允许时间,CloudFront 将限制该函数。 我们可以在测试中查看计算利用率,也可以使用 CloudWatch 查看发布后的函数的执行情况。依次进入 CloudWatch – Metrics – All metrics,确认 region 已经切换到 N. Virginia 区域,搜索 CloudFront,选择 Per-Function Metrics,选中对应 function 的 FunctionComputeUtilization 指标,进行查看。 ![image.png](https://dev-media.amazoncloud.cn/0edc5470c05746528a66798856c0fb35_image.png "image.png") **步骤七:** **CloudFront Extension 中的 CFF 应用** 上面以 CORS 为案例介绍了 CloudFront Functions 的开发及调试全流程,在亚马逊解决方案团队(CSDC)维护的 CloudFront Extension 项目中还有很多代码案例,可以供大家参考学习。CloudFront Extenstion 的 Github 链接在这里: https://github.com/awslabs/aws-cloudfront-extensions。 ## **总结** 通过本篇文章,您应该通过动手操作对 CloudFront Function 有了一个初步的了解。您现在已经有了一个小巧实用的的 CloudFront Function 的调试环境。能够在这个环境中利用 CloudFront Function 代码按照自己的需要修改 Web 请求。并且通过 Echo-Server,CloudWatch 指标和日志观察它们的运行情况。更可以通过在 Response Header 里写入的日志即时了解程序的运行状态。 **亚马逊云科技 CloudFront 部署小指南系列文章** [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) 部署小指南(一)- 快速构建 CDN 内容分发:https://dev.amazoncloud.cn/column/article/64ac21d60f1a002f2aff1c2c [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) 部署小指南 (二)- 进阶部署: https://dev.amazoncloud.cn/column/article/64b513651da59862086bbddd [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) 部署小指南 (三)- 持续部署: https://dev.amazoncloud.cn/column/article/64bf7d47d6513d1ed1129be5 [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) 部署小指南(五)- 使用 Amazon 边缘技术优化游戏内资源更新发布: https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-five/?trk=cndc-detail [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) 部署小指南(六)- Lambda\@Edge 基础与诊断: https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-six/?trk=cndc-detail ![开发者尾巴.gif](https://dev-media.amazoncloud.cn/45c1c375d8fd4db8a018713ad47bf063_%E5%BC%80%E5%8F%91%E8%80%85%E5%B0%BE%E5%B7%B4.gif "开发者尾巴.gif")
目录
亚马逊云科技解决方案 基于行业客户应用场景及技术领域的解决方案
联系亚马逊云科技专家
亚马逊云科技解决方案
基于行业客户应用场景及技术领域的解决方案
联系专家
0
目录
关闭