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

news2024/11/15 19:48:30

73a69e14d271c1960929c2e1541d53d3.gif

内容简介

本文适用于希望使用 Amazon CloudFront Functions 提升 Amazon CloudFront 边缘计算能力的用户,旨在帮助您更好的进行 CloudFront Functions 的开发、调试、测试、部署等工作。

首先我们会对 CloudFront Function 做个简单的介绍,然后分为七个步骤为您讲述如何创建一个带有 CloudFront Function 处理能力的测试环境,并开展一些相关的调试工作。

步骤一:准备基于部署小指南(二)的整体架构

步骤二:创建一个 CloudFront Function 函数

步骤三:发布函数并关联 CloudFront 分配

步骤四:CloudFront 日志输出及查询

骤五:使用 Response Header 来完成快速调试

骤六:查看 CloudFront Functions 计算利用率

骤七:CloudFront Extension 中的 CFF 应用

通过本指南,您将学会如何使用 CloudFront,快速构建一个内容分发网络,并展示分发效果。

CloudFront Function 和 

Amazon Lambda@Edge 的简单的介绍

使用 Amazon CloudFront,您可以编写自己的代码来处理 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。

本文会致力于介绍 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 Functions 控制台进行 CloudFront Function 的开发和测试。

您仅需用定义函数名称和说明即可快速创建一个 CloudFront Function。

350322601d060a2b64146a813cca2716.png

创建完成后,将会得到一个带有示例代码的 CloudFront Function,您可以在此进行代码的开发、测试和发布。在构建页面,可以对代码进行编辑(开发),同时也能看到目前线上部署的最新代码(实时标签)。

e57f51209d4fcc72f5f0b60527fc2ef2.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 部署小指南(二),搭建一个加速动静结合网站的 CloudFront 环境。在本文中,我们主要会用这个环境里动态网站的部分来完成调试。

在调试过程中,我们会主要使用/api 这个关闭缓存的 Behavior path 进行调试。利用 Echo-Sever 观察 CloudFront Function 带来的 Web 请求的改变。

步骤二:

创建一个 CloudFront Function 函数

我们以将跨源资源共享(CORS)标头添加到响应为需求通过 CloudFront Functions 的方式实现。

下面是一段添加 CORS Header 以支持跨域访问的代码案例,如果 Access-Control-Allow-Origin CORS Header 不存在,则添加该值。

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;
}

左滑查看更多

将上面的代码片段复制到控制台编辑窗口后保存更改。

d45b394e882b7760d61e586c56df3d05.png

在开发过程中,可以通过测试页面对代码进行调试,该代码会在 viewer response 阶段影响响应标头,事件类型选择 viewer response,测试阶段选择 Development,然后执行测试,测试结果如下:

8d01c1bddd38f0cfb4f06ff1b0a55d6b.png

测试函数支持模拟请求和响应的 headers、cookies、query string。我们在响应 – 响应标头下添加标头信息进行测试:

7a39c16261edac209413339b33490f88.png

获得的测试效果结果如下,可以看到如果响应中已经包含 access-control-allow-origin 响应头,则不会重复添加该值。

e9d53a5ef06de75a0556a49d6e190f8c.png

至此,我们完成了示例代码的全覆盖测试。

步骤三:

发布函数并关联 CloudFront 分配

在发布中点击添加关联,选择需要关联的 CloudFront 分配,事件类型选择 Viewer Response,缓存行为选择 /api/*,点击添加关联。关联添加完成后即可点击上面的发布函数按钮,将代码分发到关联的 CloudFront 分配上。

2bf2e2ae63c2f686e278daf439729856.png

发布完成后,可以通过 curl 命令进行测试,我们看到响应头中已经包含了 CORS 标头信息。

curl -i http://xxxx.cloudfront.net/api/test

左滑查看更多

468b432b4b97c8ff5ea05ba4b656eb08.png

步骤四:

CloudFront 日志输出及查询

上面的代码通过 Console.log 进行日志输出,生产环境下这些日志会自动发送到 CloudWatch Logs。需要注意的是,无论在哪个边缘站点运行该函数,CloudFront Functions 始终在美国东部(弗吉尼亚北部)区域( us-east-1 )中创建日志流。日志组名称的格式为

 /aws/cloudfront/function/FunctionName ,

其中 FunctionName 是您在创建函数时为函数指定的名称。

进入 CloudWatch 控制台,将 Region 切换到美国东部(弗吉尼亚北部)区域( us-east-1 ),搜索 FunctionName 找到对应的日志组,选择对应时间的日志流即可查看日志信息。

b5d26bd368b6b88bb0c131ecf0f7f0c9.jpeg

注意:在发布到生产环境时,建议删除不必要的日志输出,以节约成本。

步骤五:

使用 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 中输出。

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 不断刷新等到日志的流程,大大提高效率。调试完成后切记注释或删除日志相关的代码。

988063c8f7511e4e4fe9039d8afc8005.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 指标,进行查看。

8174b03482db01430d7e284ec80b17db.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 部署小指南(一)- 快速构建 CDN 内容分发:

https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-one/

Amazon CloudFront 部署小指南 (二)- 进阶部署:

https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-two/

Amazon CloudFront 部署小指南 (三)- 持续部署:

https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-three/

Amazon CloudFront 部署小指南(五)- 使用 Amazon 边缘技术优化游戏内资源更新发布:

https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-five/

Amazon CloudFront 部署小指南(六)- Lambda@Edge 基础与诊断:

https://aws.amazon.com/cn/blogs/china/amazon-cloudfront-deployment-handbook-part-six/

本篇作者

07c2b6c945f4a9010d64d36681d82a0f.jpeg

朱劲松

亚马逊云科技解决方案架构师,负责基于亚马逊云平台的解决方案咨询和设计,拥有 10 多年的 IT 行业工作经验,历任系统架构师、大数据总监、CTO 等职,在边缘计算、Serverless、大数据方面有丰富的实践经验。

bc944fe0c76158277437c8b6a8bb9182.jpeg

崔俊杰

亚马逊云科技高级产品解决方案架构师,负责亚马逊云科技云边缘安全相关的服务产品。为亚马逊云用户提供 DDoS 防御/网站前端安全防御/域名安全相关的产品咨询。对 Cloudfront,Shield,WAF,Route53,Global Accelerator 等云边缘安全相关产品有深入了解。在计算机安全、数据中心和网络领域有多年的工作经验。

df9137d12bbf65aafb3f6b3bd898662c.gif

5cdd5744ec527d873c0316215acf5bde.gif

听说,点完下面4个按钮

就不会碰到bug了!

d4a3c21ed356d79972f47ed6cf7d72e6.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/839449.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全志F1C200S嵌入式驱动开发(应用程序开发)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 我们在开发soc驱动的时候,很多情况下也要验证下当前的驱动功能是否正确。当然除了验证驱动功能之外,我们还要编写业务代码和流程代码。这中间就和各行各业有关了,有的是算法,有…

Redis BigKey案例

面试题: 阿里广告平台,海量数据里查询某一固定前缀的key小红书,你如何生产上限制keys*/flushdb/flushall等危险命令以防止误删误用?美团,MEMORY USAGE命令你用过吗?BigKey问题,多大算big&#…

GODOT游戏引擎简介,包含与unity性能对比测试,以及选型建议

GODOT,是一个免费开源的3D引擎。本文以unity作对比,简述两者区别和选型建议。由于是很久以前写的ppt,技术原因视频和部分章节丢失了。建议当做业务参考。 GODOT目前为止遇到3个比较重大的基于,第一个是oprea的合作奖,…

【redis】redis的认识和安装

目录 1.redis是什么2.Redis的特点3.安装redis4.设置远程连接4.1 开启隧道4.2 可视化客户端连接4.3 开启防火墙 5.redis常见数据类型5.1 redis的一些全局命令5.2 数据结构 6. redis的典型应用---缓存(cache)6.1 使用redis做缓存6.2 缓存穿透,缓…

【绪论0】

#pic_center R 1 R_1 R1​ R 2 R^2 R2 目录 知识框架No.0 引言No.1 操作系统的概念功能和定义一、操作系统的概念和定义1、电脑的演变 二、操作系统的功能和目标 No.2 操作系统的特征一、并发二、共享三、虚拟四、异步 No.3 操作系统的发展与分类一、手工操作阶段二、批处理阶段…

Windows11 家庭中文版关于本地组策略编辑器gpedit.msc找不到即打不开的解决办法(征诚小张售后实测有效)

Windows11 家庭中文版关于本地组策略编辑器gpedit.msc找不到即打不开的解决办法 根本原因:是因为Windows11家庭中文版的 版本系统没内置安装本地策略组编辑器 好了废话不多说 直接说解决办法 第一步 首先电脑上新建一个空文本文件 输入以下内容: echo o…

Android Studio安装AI编程助手Github Copilot

csdn原创谢绝转载 简介 文档链接 https://docs.github.com/en/copilot/getting-started-with-github-copilot 它是个很牛B的编程辅助工具,装它,快装它. 支持以下IDE: IntelliJ IDEA (Ultimate, Community, Educational)Android StudioAppC…

Qt应用开发(基础篇)——时间类 QDateTime、QDate、QTime

一、前言 时间类QDateTime、QDate、QTime、QTimeZone保存了Qt的时间、日期、时区信息,常用的时间类部件都会用到这些数据结构,常用概念有年、月、日、时、分、秒、毫秒和时区,时间和时区就关系到时间戳和UTC的概念。 UTC时间,又称…

FPGA初步学习之串口发送模块【单字节和字符串的发送】

串口相关简介 UART 在发送或接收过程中的一帧数据由4部分组成,起始位、数据位、奇偶校验位和停止位,如图所示。其中,起始位标志着一帧数据的开始,停止位标志着一帧数据的结束,数据位是一帧数据中的有效数据。 通常用…

【贪心算法】leetcode刷题

贪心算法无固定套路。 核心思想:先找局部最优,再扩展到全局最优。 455.分发饼干 两种思路: 1、从大到小。局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩。先遍历的胃口&a…

Win11大小写切换图标关闭方法

大家使用Win11操作系统的时候经常会切换大小写键盘,有些游戏本在游戏过程中需要切换大小写,这个时候电脑的屏幕就会出现大小写切换的图标而影响游戏体验; 那么想要关闭Win11电脑上大小写切换图标,又不知道具体怎么操作&#xff0c…

VS Code search tab

Vs Code search 栏的应用 我发现,在vs code种,上面的搜索框的功能非常多。在最初使用vscode时候,以为这只是一个普通的搜索框。后来,发现它可以用于全局搜索文件,比如使用ctrlshiftp。 后来,我发现&#xf…

lifecycleScope Unresolved reference

描述 导入了lifecycle.lifecycleScope,但是在activity中使用lifecycleScope报错出现Unresolved reference找不到引用。 导包 import androidx.lifecycle.lifecycleScope使用 lifecycleScope.launch(Dispatchers.IO) {...}错误 方案 代码中的activity继承Activ…

SSM(Vue3+ElementPlus+Axios+SSM前后端分离)--功能实现【四】

文章目录 SSM--功能实现实现功能06-修改家居信息需求分析/图解思路分析代码实现注意事项和细节 实现功能07-删除家居信息需求分析/图解思路分析代码实现 实现功能08-分页显示列表需求分析/图解思路分析代码实现完成测试分页显示效果 SSM–功能实现 实现功能06-修改家居信息 需…

39.利用matlab寻找素数(matlab程序)

1.简述 MATLAB嵌套循环允许使用一个循环在另一循环内,下面用一个嵌套循环来把所有从1到100的素数显示出来。 2.代码 %% 学习目标:寻找素数 clear sum5; %求0~100素数之和 ss0; %用来标定是否是素数,0表示不是 p…

MongoDB SQL

Microsoft Windows [版本 6.1.7601] 版权所有 (c) 2009 Microsoft Corporation。保留所有权利。C:\Users\Administrator>cd C:\MongoDB\Server\3.4\binC:\MongoDB\Server\3.4\bin> C:\MongoDB\Server\3.4\bin> C:\MongoDB\Server\3.4\bin>net start MongoDB 请求的…

Mac电脑怎么使用“磁盘工具”修复磁盘

我们可以使用“磁盘工具”的“急救”功能来查找和修复磁盘错误。 “磁盘工具”可以查找和修复与 Mac 磁盘的格式及目录结构有关的错误。使用 Mac 时,错误可能会导致意外行为,而重大错误甚至可能会导致 Mac 彻底无法启动。 继续之前,请确保您…

【C# 基础精讲】C# 开发环境搭建(Visual Studio等)

安装C#开发环境是开始学习和使用C#编程的第一步。目前,最常用的C#开发环境是Microsoft Visual Studio,它是一套强大的集成开发环境(IDE),提供了丰富的工具和功能,使开发C#应用程序变得更加便捷。以下是安装…

OSLog与NSLog对比

NSLog: NSLog的文档,第一句话就说:Logs an error message to the Apple System Log facility.,所以首先,NSLog就不是设计作为普通的debug log的,而是error log;其次,NSLog也并非是printf的简单…

Redis 6.5 服务端开启多线程源码

redis支持开启多线程,只有从socket到读取缓冲区和从输出缓冲区到socket这两段过程是多线程,而命令的执行还是单线程,并且是由主线程执行 借鉴:【Redis】事件驱动框架源码分析(多线程) 一、main启动时初始化…