AWS Lambda 的一些随笔
AWS Lambda 是什么?
AWS Lambda是亚马逊云计算服务的一部分,它是一个事件驱动、无服务器的平台。它提供计算服务,运行事件响应代码,并自动管理计算资源
简单来说,AWS Lambda
是运行在aws云上的一个函数,它接受你指定的事件驱动(调用),输出(返回)响应结果。aws允许你在一定范围内自由分配Lambda
所需要的计算资源,同时支持一定数量的并发(10000qps)。总的来说,在合适的场景下AWS Lambda
可以提供非常好的服务支持。
什么场景适合 AWS Lambda ?
- 微服务
- 对其他aws服务有依赖的开发
举两个自己用到例子:
- 某个应用页面在前端使用了echarts等库渲染图表,同时有一个邮件订阅功能可以订阅这个页面的内容。由于邮件中通常会禁用js,因此无法在邮件中显示图表。虽然echarts支持ssr渲染成svg,但是保险起见还是需要把svg转成png。然而我们的服务端并不是node,因此想到如下几个方案:
- 更换服务端为
nodejs
(???) - 安装v8引擎扩展来解析js生成想要的结果 (虽然挺绕的,但是还行)
- 部署一个
nodejs
服务,传入echarts
的配置项,生成png (中规中矩,还能更优雅吗?) - 使用
aws lambda
。相当于把nodejs
的代码原封不动上传到aws lambda,同时无需考虑部署和并发等一系列问题。
- 更换服务端为
- 应用中很多静态资源通过
AWS CloudFront
(即CDN)分发,而且实际存储在AWS S3
上面。PM想要把所有的jpg/png
升级为webp
,但是不想改现有的代码(意味着请求的url仍然是.jpg/.png
),同时也不想修改后台操作(仍然上传jpg/png
)。这个时候又轮到AWS Lambda
发光发热了:CloudFront
提供生命周期钩子函数,并且直接支持使用Lambda@Edge
(也是Lambda)CloudFront
在请求Request Viewer
(cdn的缓存层)时,使用Lambda@Edge
来判断是否需要使用webp,如果是则修改request
的uri
.比如请求的是/images/example.jpg
,经过Lambda@Edge
之后变成请求/images/example.webp
- 接下来是正常流程,
CloudFront
的Viewer
里找不到资源,就会向Origin
(通常是AWS S3
)发起请求 - 在刚开始的时候,我们的S3存储上面只有上传的源图片
example.jpg
,没有请求的example.webp
。在CloudFront
的Origin Response
上使用一个Lambda@Edge
,判断请求的资源为.webp
且未找到时(404/403),尝试从s3上提取源图片example.jpg
,然后转换成webp
格式存入s3(即Origin
,下次可以直接获取example.webp
),同时作为结果返回给Viewer
.
AWS Lambda 怎么创建?
- aws lambda控制台里web编辑器直接码起来,或者本地编辑好,复制粘贴上去
- 本地编辑调试后打包成一个zip上传,需要注意的是应该打包项目文件夹里的所有文件,而不是打包上级目录文件夹。例如项目文件结构如下:
lambda/
index.js
node_modules/
lib/
那么打包的时候应该是zip -r lambda/*
而不是zip -r lambda
3. 如果整个lambda代码比较小,zip上传后会在web编辑器里显示出来。如果超过一定大小(大概是5-10M),则不再支持web编辑器查看修改。
4. 如果lambda代码继续大到一定程度,在zip解压之后大于260M(大约),则会上传失败。这个时候需要借助layer
来降低lambda的代码量。
5. layer
可以理解为依赖库,创建layer的时候需要为其指定runtime运行时
AWS Lambda 怎么调试?
1. 测试Lambda
除了本地测试,lambda上有一些测试模板,适合测试一些特定的trigger参数
2. Lambda 日志
lambda运行的日志,可以通过CloudWatch
查看。然而通常容易忽略的一点是,AWS
划分了很多区,在不同的区调用的lambda,其产生的log只能在对应的区的CloudWatch
上查看。 因此,如果你发现找不到lambda的log,不妨试试切换不同的Region
使用 AWS Lambda 要注意哪些问题?
1. Lambda 有大小限制
前面提到过当上传的zip解压后不能大于260M,超过这个大小应该考虑借助layer
2. Lambda 运行时
Lambda的runtime只有你指定的nodejs/python基础环境,甚至找不到字体库。因此如果想要使用字体,需要把字体文件包含进lambda,并且通过环境变量指定字体文件所在目录(/opt
+项目目录)
What fonts, if any, are available in Lambda?
可能发生的另一个问题是,本地安装的依赖包(windows x86/macOS arm)可能并不能在lambda(linux)上使用。因此上传的zip中的依赖包版本,应当确保跟lambda的运行时保持一致。
3. Lambda@Edge不支持layer
这个就是不支持,Lambda@Edge
还有其他一堆的不支持,文档里写的明明白白。
4. lambda执行角色权限
如果lambda使用了trigger,需要有对应trigger的相关权限。假如代码里使用了其他服务(例如s3存储),也需要给对应角色附加对应权限。
aws的初次使用者估计会被他的权限控制折腾好一会儿,等到熟悉了一段时间后估计就能得心应手了。
5. lambda日志
前面已经提到过了,这里再次提醒。lambda的运行日志保存在其被调用的时候所在的区(Region),如果你发现找不到lambda的log,不妨试试切换不同的Region
小结
总的来说,AWS Lambda
是一个非常方便的云计算工具。它能在项目中扮演什么角色,发挥多大的作用,完全取决于开发者对其了解的程度。上面提到的也只不过是冰山一角,实际运用中可能遇到更多各种各样的问题。但是无论如何,它作为一个产品服务,其存在目的肯定是为了方便大家使用。因此只要克服文档这一关,剩下的基本上是一马平川。