AWS Lambda是一个“可简单创建Lambda函数、无需管理的计算平台”。也可以这么理解:Lambda是一个针对AWS计算资源的IFTTT脚本创建器和管理器。
举个例子:你有一个照片类应用。照片上传到S3之后,需要在DynamoDB上记录新照片的元数据。Lambda的作用就是可以有一个地方放一个触发脚本来执行这个任务,而不用关心这个脚本运行在什么机器或者虚拟机上。也可以将Lambda理解为将functions(函数)从计算资源层抽象出来的服务。
云计算只是一个执行环境,应用的根本在于三者函数(functions,即业务逻辑的载体)+数据(data,即跟业务相关的输入与输出),以及这两者之间的交互——即事件(events。常见的事件如增加、变更、删除等)。比如当发生一个事件(event)时,执行某个函数(function),输出新的数据(data)。
Lambda服务的核心概念是Lambda function(简称function,函数),目前仅支持Node.js.
围绕function可以定义情景,包括执行环境(语言、内存、超时、IAM角色)以及这个function要触发的另一个function。function的代码和有关情景的元数据均存储在AWS中,以 ARN(Amazon Resource Name)的方式被外部识别。如需包含第三方库,可以放在ZIP文件中上传。
function上传之后,开发者可以将其指定到指定的AWS资源(如某个S3 bucket,某个DynamoDB表,某个Kinesis流),然后Lambda就会建立该资源跟你的function之间的关联。当资源方面发生变动,Lambda就会去自动张罗资源去执行你的function。用于运行function的资源的创建分配和释放都有Lambda自动来做,开发者完全不需要去干预。
每一个function具有双重的IAM角色:一个是触发角色(invocation role),决定Lambda执行某个function的权限;另一个是执行角色(execution role),决定该function操作AWS资源的权限。
基于Lambda服务,我们可以做IOT生态环境下devices的动态部署和升级
AWS的lambda函数将文件上传到S3 bucket。我们期望的文件是一个包含topic,value,retain域的JSON格式配置文件,这些域映射到使用NodeJS发送MQTT消息的基本例子。JSON文件如下:
{
"topic":"873bfdf00b00775c8c6fb16aa1554401/lambda",
"value": "hello wallace",
"retain": false
}
上传脚本upload.sh,置于目录“kmr-send-mqtt”下,该脚本被用来打包一个nodejs zip 应用作为Lambda函数
脚本执行后生成Lambda 函数index.handler#! /bin/bashROLE="[your role arn]"HANDLER="index.handler"MEMORY=128TIMEOUT=10rm -rf node_modules/npm installFUNCTION=`basename \`pwd\``PACKAGE="$FUNCTION.zip"rm -rf ${PACKAGE}zip -r ${PACKAGE} *.js node_modules @ --exclude=*aws-sdk*aws lambda upload-function \--function-name "$FUNCTION" \--function-zip "${PACKAGE}" \--role "$ROLE" \--mode event \--handler "${HANDLER}" \--memory-size ${MEMORY} \--timeout ${TIMEOUT} \--runtime nodejs
对于的NodeJS runtime 文件 "package.json",which along side the upload.sh script
{
"name": "lambda-mqtt","version": "0.0.1","description": "MQTT from lambda","main": "index.js","dependencies": {"mqtt": "^0.3.13"}}lambda函数将读取事件源的输入事件并解析了S3对象的bucket和key。我们将使用AWS JavaScript SDK来获取对象,读到内存里并解析了MQTT上下文。然后,将启动MQTT客户端根据我们上传配置文件中的要求发送消息,。
NodeJS包中mian函数对应index.JS脚本,这是Lambda的执行角色
var mqtt=require('mqtt');
var AWS=require('aws-sdk');
var s3=newAWS.S3();
exports.handler=function(event,context){
console.log(JSON.stringify(event,null,''));
console.log(JSON.stringify(event.Records[0],null,''));
response=s3.getObject({Bucket:event.Records[0].s3.bucket.name,Key:event.Records[0].s3.object.key},function(err,data) {
var message = JSON.parse(data.Body.toString());
client= mqtt.connect("mqtt://[thingfabric username]:[thingfabric MD5 secret hash]@q.m2m.io:1883");
client.publish(message.topic, message.value, {retain: (message.retain !=null)&&message.retain});
client.end();
client.on("close", (function() {return context.done(null,"DONE");}));
client.on("error", (function () {return context.done(null,"ERROR");}));
});
};
Lambda作为触发角色,需要跟某个AWS资源关联,比如某个Kinesis流
aws lambda add-event-source \ --region us-east-1 \ --function-name ProcessKinesisRecords \ --role invocation-role-arn \ --event-source kinesis-stream-arn \ --batch-size 100 \ --profile adminuser这样在该Kinesis流发生变化时会触发Lambda。