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

news2024/11/16 6:03:02

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 response
    const response = event.Records[0].cf.response;
    const headers = response.headers;
    
    let region = process.env.AWS_REGION;
    console.log("region: ", region);


    //Set new headers
    headers['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 response
    callback(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.coloradmin.cn/o/901044.html

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

相关文章

干货|工作中要使用Git,看这篇文章就够了

本文将从 Git 入门到进阶、由浅入深,从常用命令、分支管理、提交规范、vim 基本操作、进阶命令、冲突预防、冲突处理等多方面展开,足以轻松应对工作中遇到的各种疑难杂症,如果觉得有所帮助,还望看官高抬贵手给个赞呗,感…

回归预测 | MATLAB实现BES-SVM秃鹰搜索优化算法优化支持向量机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现BES-SVM秃鹰搜索优化算法优化支持向量机多输入单输出回归预测(多指标,多图) 目录 回归预测 | MATLAB实现BES-SVM秃鹰搜索优化算法优化支持向量机多输入单输出回归预测(多指标,多图)效…

第16集丨一起创建Vue脚手架吧

目录 一、安装Vue CLI1.1 配置 npm 淘宝镜像1.2 全局安装1.3 验证是否成功 二、创建vue_test项目2.1 cmd进入桌面2.2 创建项目2.3 运行项目2.4 查看效果 三、脚手架结构分析3.1 文件目录结构分析3.2 vscode终端打开项目 一、安装Vue CLI CLI:command-line interface…

re学习(33)攻防世界-secret-galaxy-300(脑洞题)

下载压缩包: 下载链接:https://adworld.xctf.org.cn/challenges/list 参考文章:攻防世界逆向高手题之secret-galaxy-300_沐一 林的博客-CSDN博客 发现这只是三个同一类型文件的三个不同版本而已,一个windows32位exe&#xff0…

VBA技术资料MF45:VBA_在Excel中自定义行高

【分享成果,随喜正能量】可以不光芒万丈,但不要停止发光。有的人陷入困境,不是被人所困,而是自己束缚自己,这时"解铃还须系铃人",如果自己无法放下,如何能脱困? 。 我给V…

【C++】C++ 语言对 C 语言的加强 ③ ( 类型检查增强 - 所有函数和变量必须有类型 | 新增 bool 类型 - bool 类型简介 )

文章目录 一、类型检查增强 - 所有函数和变量必须有类型1、C 语言函数类型 - 函数参数与返回值类型可以不确定2、C 语言函数类型 - 函数参数与返回值类型必须写明 二、新增 bool 类型 - bool 类型简介 一、类型检查增强 - 所有函数和变量必须有类型 1、C 语言函数类型 - 函数参…

arduino Xiao ESP32C3 oled0.96 下雪花

Xiao ESP32C3使用oled 0.96实现下雪的功能 雪花下落的时候, 随机生成半径和位置 sandR和sandX,sandY 保存雪花下落位置的时候, 将其周边一圈设置为-1, 标记为有雪花 其他雪花下落的时候, 其他雪花的一圈如果遇到-1, 则停止下落, 并重复2 #include "oled.h" void …

Java反射机制 (秒懂百科)

一、什么是反射? 反射允许对成员变量,成员方法和构造方法的信息进行编程访问。。 反射是一种机制。对于任何一个类,都能知道这个类的所有属性和方法。对于任何一个对象,都能调用这个对象的所有属性和方法。这种动态获取类的信息和…

【推荐】深入浅出bean的生命周期

目录 1.spring 管理JavaBean的过程(生命周期) 2.spring的JavaBean管理中单例模式及原型(多例)模式 2.1 . 默认为单例,但是可以配置多例 2.2.举例论证 2.2.1 默认单例 2.2.2 设置多例 2.2.3单例与多例的初始化的时…

记录win 7旗舰版 “VMware Alias Manager and Ticket Service‘(VGAuhService)启动失败。

记录win 7旗舰版 "VMware Alias Manager and Ticket Service’(VGAuhService)启动失败。 描述如图 https://learn.microsoft.com/zh-CN/cpp/windows/latest-supported-vc-redist?viewmsvc-140#visual-studio-2015-2017-2019-and-2022 安装对应版本的VC 库就可以解决问…

重磅Redis 7 发布,有哪些新特性?

Redis 7.2.0 现已发布,这是首个 Unified Redis Release。此版本包含一系列广泛的新功能,以及对人工智能计划功能支持的重大投资。 公告称,这是 “影响最深远的版本。在每一项增强功能中,你都能感受到一个强烈的主题:让…

idea使用docker生成镜像(打包镜像,导入镜像,导出镜像)

1:先下载安装dockerdesktop,安装成功后 2: 在cmd执行docker -v,查看安装的docker版本 C:\Users\dell>docker -v Docker version 24.0.5, build ced09963:需要启动 dockerdesktop应用,才算启动docker&a…

k8s基本概念、k8s对象、三个命令玩转所有的yaml写法、给vscode安装插件、kubectl和kubelet及自动补全

文章目录 1、K8S基本概念2、kubernetes Objects(k8s对象)2.1、定义2.2、对象的spec和status2.3、如何写任意资源的yaml(以Pod为例)2.4、pod的yaml文件2.5、k8s对象yaml的结构2.6、管理k8s对象2.7、对象名称2.8、名称空间2.9、标签…

Leetcode 0814周总结

本周刷题: 88, 108, 121, 219, 228, 268, 283, 303, 349, 350, 414, 448 88 合并两个有序数组 nums1{1, 2, 3 ,0, 0, 0} nums2{2, 5, 6} 合成效果:nums1{1, 2, 2, 3, 5, 6} 思路:【双指针】对两个数组设置双指针,依次比较哪…

transform模型讲解

目录 game是游戏 与北京在一起:冬奥会 transform :encode,decode 12步骤 自注意力机制就是变形金刚的拆解对照:生成零部件V和权重K,前馈神经网络进行权重调节:初步变形 编码器Attention就是考虑上下文信…

Spring学习笔记+SpringMvc+SpringBoot学习笔记

壹、核心概念: 1.1. IOC和DI IOC(Inversion of Control)控制反转:对象的创建控制权由程序转移到外部,这种思想称为控制反转。/使用对象时,由主动new产生对象转换为由外部提供对象,此过程种对象…

阿里云服务器扩容数据盘/系统盘小记

参考:扩容分区和文件系统(Linux) 阿里云的教程写的倒是详细,就是太细节,不利于阅读。 1 确认分区数据盘的属性 运行以下命令,确认待扩容云盘及其分区信息。 fdisk -lu设备: ①:云…

线性筛选素数

线性筛选素数 问题 求取范围[2,n] 之间的所有素数 方法一 方法一概述 使用数字prime[i]来标记i是否为素数。初始化prime[2…n]1。 当处理到数字i时,若prime[i]0,则代表2到i-1中有i的因子,因此i为合数;若prime[i]1&#xff0c…

美团——城市低空物流无人机的设计挑战与应对

城市低空物流无人机的设计挑战与应对 强度分析 振动影响 动力设计 噪声设计 冗余备份更加性价比,便宜好实现 航电系统 动力系统的冗余 电池系统的冗余 通讯系统等冗余 降落冗余 安全降落 计算高效 产线标定 底层基础库 离线系统 行业公开测评 未来展望 – 导航定…