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

1822cca71d813dc2cab888d7714bf949.gif

内容简介

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

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

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

  • 步骤二:创建一个 Lambda 函数

  • 步骤三:添加 CloudFront 触发器来运行函数

  • 步骤四:CloudFront Lambda@Edge 日志输出及查询

  • 步骤五:使用 Response Header 提升调试效率

  • 步骤六:查看 Lambda@Edge 资源利用率

  • 步骤七:CloudFront Extension 中的 CFF 应用

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

CloudFront Function 

和 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 文档。

本文会致力于介绍 CloudFront Lambda@Edge,有关 

CloudFront Functions 的详细介绍可以参考 Amazon CloudFront 部署小指南(四)-  CloudFront Function 基础与诊断。

如下图所示,Lambda@Edge 既可以放在 Viewer 阶段,又可以放在 Origin 阶段。Lambda@Edge 非常适合以下场景:

  • 需要几毫秒或更长时间才能完成的函数。

  • 需要可调节 CPU 或内存的函数。

  • 依赖于第三方库(包括 Amazon 开发工具包,用于与其他 Amazon 服务集成)的函数。

  • 需要网络访问才能使用外部服务进行处理的函数。

  • 需要文件系统访问或访问 HTTP 请求正文的函数。

47c1dffe863936bd22726af3c336425b.jpeg

如何开始 

CloudFront Lambda@Edge 的开发

CloudFront Lambda@Edge 是 Lambda 的扩展,实际使用时也是先完成 Lambda 的开发、测试、部署,然后将其与 CloudFront 分配相关联,CloudFront 则会将 Lambda 分发到边缘站点,在边缘站点中截获请求和响应进行处理,可以显著的减少延迟并改善用户体验。

与 Lambda 不同的是,Lambda@Edge 只支持 Node.js 和 Python 作为开发语言,且必须创建在 US East(N. Virginia)区域,它会自动分发到各个边缘站点去执行。更多对 Lambda@Edge 的限制可以参考开发人员指南。

下面我们就着手搭建一个最小的 CloudFront Lambda@Edge 环境。

步骤一: 

准备基于部署小指南(二)的整体架构,来进行部署过程的演示

首先,让我们基于 CloudFront 部署小指南(二),搭建一个加速动静结合网站的 CloudFront 环境。在本文中,我们主要会用这个环境里动态网站的部分来完成调试。

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

步骤二:

创建一个 Lambda 函数

您可以参考官方文档第三步,通过使用蓝图来快速创建一个修改响应头的示例函数。使用以下代码进行测试,以下代码中增加了 AWS_REGION 环境变量的输出,并和自定义的 function-version 一起放在 header 中返回给客户端。

官方文档第三步:https://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/lambda-edge-how-it-works-tutorial.html#lambda-edge-how-it-works-tutorial-create-function

如果想了解更多环境变量,可以参考官方文档检索环境变量。

*注意,修改响应头的函数需要关联 CloudFront 的 Viewer Response 或者源响应(Origin Response)事件,并且修改的是 CloudFront 的 response event 数据结构。该数据结构在 Viewer Request 和 Origin Request 事件里是无法获取的。

'use strict';
exports.handler = (event, context, callback) => {//Get contents of responseconst response = event.Records[0].cf.response;const headers = response.headers;let region = process.env.AWS_REGION;console.log("region: ", region);//Set new headersheaders['strict-transport-security'] = [{key: 'Strict-Transport-Security', value: 'max-age= 63072000; includeSubdomains; preload'}];headers['content-security-policy'] = [{key: 'Content-Security-Policy', value: "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"}];headers['x-content-type-options'] = [{key: 'X-Content-Type-Options', value: 'nosniff'}];headers['x-frame-options'] = [{key: 'X-Frame-Options', value: 'DENY'}];headers['x-xss-protection'] = [{key: 'X-XSS-Protection', value: '1; mode=block'}];headers['referrer-policy'] = [{key: 'Referrer-Policy', value: 'same-origin'}];headers['function-version'] = [{key: 'Function-Version', value: 'V01'}];headers['function-region'] = [{key: 'Function-Region', value: region}];//Return modified responsecallback(null, response);
};

左滑查看更多

步骤三:

添加 CloudFront 触发器来运行函数

您可以参考官方文档第四步,为 Lambda 函数配置 CloudFront 触发器以运行您的函数。这儿您可以选择步骤一中提前创建好的 CloudFront 分配,缓存行为选择 /api/*,这一次,CloudFront 事件类型我们选择源响应(Origin Response),勾选确认部署到 Lambda@Edge,点击部署。

官方文档第四步:https://docs.aws.amazon.com/zh_cn/AmazonCloudFront/latest/DeveloperGuide/lambda-edge-how-it-works-tutorial.html#lambda-edge-how-it-works-tutorial-add-trigger

22096873054bb1a900d76d8058cd036f.jpeg

部署完成后,可以通过 curl 命令进行测试,我们看到响应头中已经包含了在 Lambda 中添加的标头信息。

注意:Lambda@Edge 的部署需要一些时间,可以进入 CloudFront 分配中的常规页面查看上次修改时间,确认部署进度。

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

左滑查看更多

c37253ee9c994b4134d982fca117a994.jpeg

更新 Lambda@Edge 函数

方式一:在 Lambda 控制台重新发布

对于已经部署到 Lambda@Edge 的函数,如果在 Lambda 中修改了代码,需要先点击部署(Deploy)按钮,保存修改后的代码。然后重复步骤三,将修改后的函数部署到 Lambda@Edge。

方式二:发布新版本后,更新 CloudFront

部署(Deploy)之后,切换到版本标签页,点击发布新版本进行发布,发布后会得到一个新的版本号,然后到 CloudFront 控制台选择需要部署的目标分配,在行为(Behavior)中选择对应的行为,点击编辑按钮,在最下面的函数关联中更新函数 ARN/名称为刚刚生成的版本号,点击保存更改

对于需要同时更新源请求源响应的场景,可以采取方式二,同时变更源请求源响应的版本,这样 CloudFront 在部署的时候则可以同时更新两个函数。

c5bf3788a1342bbb7aaa281e124bbb4c.jpeg

步骤四:

CloudFront Lambda@Edge 日志输出及查询

使用 Console.log 进行日志输出,Lambda@Edge 会自动将日志发送到 CloudWatch 日志组,在函数运行的 Amazon 区域中创建日志流,日志组名称的格式为 

 /aws/lambda/us-east-1.function-name ,

其中 function-name 是您在创建函数时为函数指定的名称, us-east-1 是运行函数的 Amazon 区域的区域代码。

Lambda@Edge 的日志存放在函数实际执行的区域,而非函数部署的区域( us-east-1 ),所以在调试的时候,需要先确定函数执行的区域,在 CloudWatch 控制台中切换到对应的区域,搜索 function-name 进入日志组方能查看最新日志。在不确定执行区域的情况下,如果在各个区域之间不停的切换,查找日志信息,极其耽误时间。而且由于日志存在延迟,还会出现明明找对了区域,但是因为延迟而错过日志,然后不停的在错误区域中寻找,耽误了宝贵的时间。

官方文档中提到的通过在 CloudFront 控制台上查看对应函数的指标图表的方式,由于是统计信息,在请求非常少的时候或许适用,如果多个区域都存在一定的请求数量,就比较难判断。

通过 Header 中的 X-Amz-Cf-Pop 值,可以获得当前请求所对应的边缘位置编号,通过 Amazon CloudFront CDN Edge Locations 网站查找可以指导其对应的国家和城市,可以在其邻近的区域中查找日志。

这里介绍一种可以快速准确的获得函数每一次执行所在区域的方法,就是获取 AWS_REGION 环境变量,并在 Response Header 中返回。这里的 AWS_REGION 指的是执行 Lambda 函数的 Amazon 区域。

实现方式:

如果您已经创建了用于源响应(Origin Response)的 Lambda 代码,则在代码中返回修改后的 response 之前添加下面这行代码:

event.Records[0].cf.response.headers['execution-region'] = [{key: 'Execution-Region', value: process.env.AWS_REGION}];

左滑查看更多

如果您只创建了用于源请求(Origin Request)的 Lambda 代码,则建议您使用以下代码创建一个用于源响应(Origin Response)的 Lambda 代码,并部署到 Lambda@Edge。

'use strict';
exports.handler = (event, context, callback) => {event.Records[0].cf.response.headers['execution-region'] = [{key: 'Execution-Region', value: process.env.AWS_REGION}];callback(null, response);
};

左滑查看更多

下面是响应结果示例,只要能获得相应,就可以通过 response header 获悉执行函数的区域,接下来就可以在 CloudWatch 控制台中切换到该区域等待日志的出现。

ef69dbef261000fbc6b644e386f16a08.jpeg

注意:在发布到生产环境时,建议删除不必要的日志输出,以节约成本。如有需要,还可以禁用 Lambda 对 CloudWatch 日志输出的权限杜绝任何日志,将执行角色中的 Allow:logs:PutLogEvents 移除。

步骤五:

使用 Response Header 提升调试效率

遇到在线调试的场景,可以通过在 Response Header 中添加版本标头的方式,来确定当前请求使用的是哪个版本的代码。在每次更新代码的时候需使用新的版本号,可以参考上面代码中的 Function-Version。

调试的时候,如果想打印查看某个变量的值,可以将该变量转换为 string 类型放到 Response Header 中输出。这样可以在得到响应结果后即可查看该值,无需再到控制台中查看,大大提高效率。

该方法在 Amazon CloudFront 部署小指南(四)-  CloudFront Function 基础与诊断中有详细介绍,思想和方式上都非常相似,可以参考。

使用 response header 输出信息进行调试的时候,需要遵循 response header 的规范,value 必须是 string 类型,且只有 CloudFront Function 执行正常将 response 完整返回给客户端时才能看到相关信息。如果代码执行异常,中断的情况,则无法获得正常响应,此时无法通过 response header 查看调试信息,这种情况下 console.log()可以将异常中断前的日志都打印出来。我们在实际开发测试时可以结合使用。

步骤六:

查看 Lambda@Edge 资源利用率

我们可以通过 CloudWatch Logs 查看函数执行时长以及使用的内存信息。建议在发布到生产环境之前,使用 Lambda Power Tuning 进行测试,以获得最佳的内存配置。

c8ce5ed12fb34f8ca90b869a2295596e.jpeg

步骤七:

CloudFront Extension 中的 Lambda@Edge 应用

上面以修改 HTTP Response 为案例介绍了 CloudFront Lambda@Edge 的开发及调试全流程,在亚马逊解决方案团队(CSDC)维护的 CloudFront Extension 项目 中还有很多代码案例,可以供大家参考学习。CloudFront Extenstion 的 Github 链接在这里:aws-cloudfront-extensions。

总结

通过本篇文章,您应该通过动手操作对 CloudFront Lambda@Edge 有了一个初步的了解。您现在已经有了一个小巧实用的 CloudFront Lambda@Edge 的调试环境,能够在这个环境中利用 CloudFront Lambda@Edge 代码按照自己的需要修改 Web 请求,并且通过 Echo-Server、CloudWatch 指标和日志观察它们的运行情况,更可以通过在 Response Header 里写入的日志头即时了解函数执行所在的区域以及程序的运行状态。

亚马逊云科技 CloudFront 部署小指南系列文章

点击标题,即可查看往期文章:

Amazon CloudFront 部署小指南(一)- 快速构建 CDN 内容分发

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

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

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

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

本篇作者

cbbc4270ecb71f50ce9caaeee95e5187.jpeg

朱劲松

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

b8b466c5f87a861a94fd5d71d0ba9b93.jpeg

崔俊杰

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

c315ed3b0433065249cae2ce81dd4940.gif

8bda37f504f918941c91a89246ccec1a.gif

听说,点完下面4个按钮

就不会碰到bug了!

dd5cb9bec29d0c1ce2da8d3de03c69a0.gif

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

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

相关文章

kafka--kafka的基本概念-副本概念replica

三、kafka的基本概念-副本概念replica Broker 表示实际的物理机器节点 Broker1中的绿色P1表示主分片Broker2中的蓝色P1表示副本分片,其余类似,就是主从的概念,如果一个Broker挂掉了,还有其它的节点来保证数据的完整性 P可以看做分…

OpenCV实例(九)基于深度学习的运动目标检测(三)YOLOv3识别物体

基于深度学习的运动目标检测(三)YOLOv3识别物体 1.基于YOLOv3识别物体2.让不同类别物体的捕捉框颜色不同3.不用Matplotlib实现目标检测 目标检测,粗略地说就是输入图片/视频,经过处理后得到目标的位置信息(比如左上角和…

Android岗位技能实训室建设方案

一 、系统概述 Android岗位技能作为新一代信息技术的重点和促进信息消费的核心产业,已成为我国转变信息服务业的发展新热点:成为信息通信领域发展最快、市场潜力最大的业务领域。互联网尤其是移动互联网,以其巨大的信息交换能力和快速渗透能力…

leetcode做题笔记92. 反转链表 II

给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 。 示例 1&#xff1a; 思路一&#xff1a;头插法 struct ListNode *reverseBetween(struct ListNode *h…

河北人事档案管理系统

河北人事档案管理系统是一个集数字化管理、高效服务、安全可靠于一体的人事档案管理平台&#xff0c;可以集中管理机关事业单位人事档案、农村党员档案、参保职工档案、流动人才档案等&#xff0c;并实现高效、便捷的查阅和调阅服务。 河北人事档案管理系统的建设主要是为了更好…

成集云 | 电子签署集成腾讯云企业网盘 | 解决方案

源系统成集云目标系统 方案介绍 电子签署是通过电子方式完成合同、文件或其他文件的签署过程。相较于传统的纸质签署&#xff0c;电子签署具有更高效、更便捷、更安全的优势。 在电子签署过程中&#xff0c;使用电子签名技术来验证签署者的身份并确保签署文件的完整性。电子…

华为OD七日集训第1期 - 按算法分类,由易到难,循序渐进,玩转OD(文末送书)

目录 一、适合人群二、本期训练时间三、如何参加四、7日集训第一期 ~ 华为OD初体验五、精心挑选21道高频100分经典题目&#xff0c;作为入门。第1天、逻辑分析第2天、字符串处理第3天、数据结构第4天、双指针第5天、递归回溯第6天、二分查找第7天、贪心算法 && 二叉树 …

dirsearch目录扫描工具的使用

文章目录 工具下载及环境准备查看帮助信息进行目录扫描 官方介绍 &#xff1a;An advanced command-line tool designed to brute force directories and files in webservers, AKA web path scanner 一个高级命令行工具&#xff0c;用于暴力破解网络服务器中的目录和文件&…

C++中List的实现

前言 数据结构中&#xff0c;我们了解到了链表&#xff0c;但是我们使用时需要自己去实现链表才能用&#xff0c;但是C出现了list将这一切皆变为现。list可以看作是一个带头双向循环的链表结构&#xff0c;并且可以在任意的正确范围内进行增删查改数据的容器。list容器一样也是…

【JVM】运行时数据区——自问自答

Q:Java 运行时数据区解构&#xff0c;哪些数据线程独占&#xff0c;哪些是线程共享&#xff1f;每个区域会产生GC和异常吗&#xff1f; 运行时数据区&#xff1a; 1、PC寄存器 2、堆区 3、JVM栈 4、Native栈 5、方法区 其中&#xff0c;PC寄存器、Native栈、JVM栈是线程独占的…

如何在pycharm中指定GPU

如何在pycharm中指定GPU 作者:安静到无声 个人主页 目录 如何在pycharm中指定GPU打开编辑配置点击环境变量添加GPU配置信息推荐专栏在Pycharm运行程序的时候,有时候需要指定GPU,我们可以采用以下方式进行设置: 打开编辑配置 点击环境变量 添加GPU配置信息 添加名称:CU…

geacon_pro配合catcs4.5上线Mac、Linux

我的个人博客: xzajyjs.cn 一些链接 Try师傅的catcs4.5项目: https://github.com/TryGOTry/CobaltStrike_Cat_4.5&#xff0c;最新版解压密码见&#xff1a;https://www.nctry.com/2708.html geacon_pro: https://github.com/testxxxzzz/geacon_pro BeaconTool.jar: https:/…

【LLM评估篇】Ceval | rouge | MMLU等指标

note 一些大模型的评估模型&#xff1a;多轮&#xff1a;MTBench关注评估&#xff1a;agent bench长文本评估&#xff1a;longbench&#xff0c;longeval工具调用评估&#xff1a;toolbench安全评估&#xff1a;cvalue&#xff0c;safetyprompt等 文章目录 note常见评测benchm…

ubuntu20搭建环境使用的一下指令

1.更新源 sudo vim etc/apt/sources.listdeb http://mirrors.aliyun.com/ubuntu/ xenial main deb-src http://mirrors.aliyun.com/ubuntu/ xenial maindeb http://mirrors.aliyun.com/ubuntu/ xenial-updates main deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates…

Redis实现共享Session

Redis实现共享Session 分布式系统中&#xff0c;sessiong共享有很多的解决方案&#xff0c;其中托管到缓存中应该是最常用的方案之一。 1、引入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM…

openGauss学习笔记-44 openGauss 高级数据管理-存储过程

文章目录 openGauss学习笔记-44 openGauss 高级数据管理-存储过程44.1 语法格式44.2 参数说明44.3 示例 openGauss学习笔记-44 openGauss 高级数据管理-存储过程 存储过程是能够完成特定功能的SQL语句集。用户可以进行反复调用&#xff0c;从而减少SQL语句的重复编写数量&…

SpringBoot 学习(03): 弱语言的注解和SpringBoot注解的异同

弱语言代表&#xff1a;Hyperf&#xff0c;一个基于 PHP Swoole 扩展的常驻内存框架 注解概念的举例说明&#xff1b; 说白了就是&#xff0c;你当领导&#xff0c;破烂事让秘书帮你去安排&#xff0c;你只需要批注一下&#xff0c;例如下周要举办一场活动&#xff0c;秘书将方…

sql server安装报错 合成活动模板库(ATL) 失败

错误 “合成活动模板库(ATL) 规则失败“ 解决办法&#xff1a; 进入SQL Server 2008R2安装包目录找到文件&#xff1a;sqlsupport_msi&#xff0c;安装此文件之后&#xff0c;再安装SQL Server&#xff0c;便可解决该问题。C:\SQL Server 2008R2\new\SQL Server 2008R2\2052_CH…

java Spring Boot yml多环境拆分文件管理优化

上文 java Spring Boot yml多环境配置 我们讲了多环境开发 但这种东西都放在一起 还是非常容易暴露信息的 并且对维护来讲 也不是非常的友好 这里 我们在resources下创建三个文件 分别叫 application-pro.yml application-dev.yml application-test.yml 我们直接将三个环境 转…

Android 广播发送流程分析

在上一篇文章中Android 广播阻塞、延迟问题分析方法讲了广播阻塞的分析方法&#xff0c;但是分析完这个问题&#xff0c;自己还是有一些疑问&#xff1a; 广播为啥会阻塞呢&#xff1f;发送给接收器就行了&#xff0c;为啥还要等着接收器处理完才处理下一个&#xff1f;由普通…