在使用AWS进行开发的时候,Lambda可以说是最为基本的程序单位了。下面就介绍一下AWS Lambda。

Lambda介绍
说白了,Lambda就是在不搭建自己服务器的前提下还能调用自己函数的一种方式。当然,Lambda的运行肯定是需要服务器的,只不过AWS把这些EC2服务器对用户都隐藏了。在创建Lambda的时候,可以选择Javascript,Python,Java,Go,Ruby,C#等众多语言。Lambda的收费取决于其运行时长,使用的AWS资源,比如内存等因素。
在每次用户调用Lambda的时候,通常是这样一个过程:
- 用户对Lambda的地址发出调用请求
- AWS的Load Balancer(对用户隐藏)获得请求
- Load Balancer从预留的EC2(对用户隐藏)中获取一个(或多个)实例并运行Lambda
- 将结果返回用户
Lambda中有很多实用的功能。比如:Lambda Edge能将同一个Lambda部署到不同区域,这样能够保证不同区域的用户调用时的低延迟。Lambda Destinations能够自动将Lambda的输出发送给其他AWS服务。Preserved concurrency则能有效解决其冷启动的问题。
EC2 vs Lambda
EC2最大的优点是其灵活性,一旦有了EC2,你就是管理员,可以在上面安装配置任何软件。
但EC2的缺点就是自己考虑其安全性,运行成本,性能等因素。在使用EC2部署大型应用时,还需要考虑Load Balancer, Target Groups, Auto Scaling Groups, EC2s等。非常灵活,但维护成本高。
Lambda的最大优点就是将这些负载均衡,自动扩容,服务器安全性管理等工作对开发者隐藏了。这样开发者就能专注于代码。在损失灵活性的代价下,获得更低的维护成本
EC2 | Lambda | |
---|---|---|
灵活性 | 非常灵活 | 不灵活 |
维护成本 | 高 | 非常低,只需考虑代码 |
收费模式 | EC2租赁费用 | 和内存,调用次数,调用时间相关 |
集成 | 需要自己做一些工作才能和AWS其他服务集成 | 非常容易和其他AWS服务结合 |
开发速度 | 慢 | 非常快 |
应用场景 | 适合流量稳定的应用,要求低延迟的应用 | 适合流量变化不规则的应用 |
典型应用 | 事件处理,工作流 |
Lambda使用场景
- Serverless CRON jobs
- 和SNS/SQS集成进行事件处理
- 和S3集成进行文件处理
- 作为Step Function构建工作流的关键部件进行业务逻辑处理
- API Gateway Integration
Lambda之间的彼此调用
访问策略
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction",
"lambda:InvokeAsync"
],
"Resource": "arn:aws:lambda:eu-west-1:xxxxxx:function:*"
}
]
}
被调用的Lambda
exports.handler = async (event) => {
const response = {
statusCode: 200,
body: JSON.stringify('Hello from callee lambda')
}
return response
}
调用Lambda
新建一个Lambda,同时为其绑定一个具有前面访问策略的Role。
let AWS = require('aws-sdk');
const lambda = new AWS.Lambda({region: 'eu-west-1'});
function invokeLambdaDemo(payload)
let params = {
FunctionName: 'calleeLambda',
InvocationType: 'Event',
Payload: JSON.stringify(payload),
LogType: 'Tail'
}
return new Promise((resolve, reject) => {
lambda.invoke(params, (err,data) => {
if (err) {
console.log(err, err.stack);
reject(err);
}
else {
console.log(data);
resolve(data);
}
});
});
}
exports.handler = async function(event, context) {
const payload = {
'message': 'Hello from caller lambda'
};
await invokeLambdaDemo(payload);
context.done();
};
Lambda Throttling
在默认情况下,调用Lambda的limit是1000个concurrent调用。这一限制针对同一region下所有的Lambda。
解决方法:
- 联系AWS客服提高这个limit
- 针对每个函数设置reserved concurrency
- 设置一个DLQ来捕获一场
- 针对throttling设置alarm
关于冷启动
当第一次调用Lambda的时候,AWS需要创建一个MicroVM,同时把Lambda代码从S3装载到MicroVM中,这个过程需要一些时间,我们管它叫做Cold Start。
可以通过CloudWatch Event来对Lambda预热,比如每5分钟调用一次Lambda
在定义一些公用变量的时候,最好能够放在handler之外,这样就可以复用,进而提高效率
在Lambda中可以使用/tmp下512MB的空间,可用做缓存
同时也可以设置Reserved Capacity来保留AWS资源以做出及时响应。
- 如果有稳定的流量,使用Reserved Capacity较为合适
- 否则,可以使用Lambda预热来确保响应时间
Scaling/Reserved Capacity
对于同一个region,AWS在默认情况下会分配1000个slot,以响应并发请求。一旦出现并发请求,在当前激活lambda不够用的时候,会cold start新的lambda以处理新请求。但需要注意的是,这1,000个配额是针对所有lambda的总和。如果请求超过1,000个,则会发生throttling。同时需要注意,Lambda的最长运行时间不能超过15分钟。
要想解决这个问题,就需要使用reserved capacity。比如:针对lambda1,分配200个slot,针对lambda2,分配500个slot,针对lambda3,分配300个slot。
关于Lambda能够使用存储空间限制的问题
在默认情况下,Lambda只能使用512MB临时存储空间,但在2022年的时候,AWS允许Lambda使用最多10 GB的空间:
https://aws.amazon.com/blogs/compute/using-larger-ephemeral-storage-for-aws-lambda/
在serverless中可以这样:
https://www.serverless.com/framework/docs/providers/aws/guide/functions
functions:
helloEphemeral:
handler: handler.handler
ephemeralStorageSize: 1024