执行和调用 Lambda 函数
本章将详细说明执行和调用 Lambda 函数的过程及其涉及的步骤。
AWS Lambda 执行模型
AWS 执行取决于为 AWS Lambda 函数添加的配置详细信息。创建函数时,会分配内存和时间,用于执行 AWS Lambda 函数。
借助配置详细信息,AWS Lambda 创建执行上下文。执行上下文是一个临时的运行时环境,它准备好了任何外部依赖项,例如数据库连接、http 端点、第三方库等(如果有)。
首次调用 AWS Lambda 函数或更新 lambda 函数时,由于执行上下文设置,几乎不会增加延迟。但是,与第一次调用相比,后续调用速度更快。如果调用 Lambda 函数所用时间较短,AWS Lambda 会尝试再次重用执行上下文。
执行上下文的重用具有以下含义 −
如果为执行 Lambda 建立了任何数据库连接,则将维护该连接以供重用。因此,Lambda 代码必须首先检查连接 - 如果存在并重用;否则我们必须建立新的连接。
执行上下文在 /tmp 目录中维护 500MB 的磁盘空间。所需的数据缓存在此目录中。您可以在代码中进行额外检查以查看数据是否存在。
如果在调用 Lambda 函数时回调或某些后台进程未完成,则在再次调用 lambda 函数时将开始执行。如果您不需要这样的事情发生,请确保在函数执行完成时您的所有进程都正确结束。
您应该使用执行上下文和存储在 tmp 目录中的数据。您必须在代码中添加必要的检查,以查看在创建新数据之前是否存在所需数据。这将节省执行时间并使其更快。
调用 AWS Lambda 函数
我们可以使用 aws cli 手动调用 AWS。我们已经了解了如何使用 cli 创建和部署 AWS Lambda。在这里,我们将首先使用 aws cli 创建一个函数并调用该函数。
使用 AWS CLI 创建 AWS Lambda 函数
您可以使用以下命令使用 aws cli −
创建 AWS Lambda 函数命令
create-function --function-name <value> --runtime <value> --role <value> --handler <value> [--code <value>] [--description <value>] [--timeout <value>] [--memory-size <value>] [--environment <value>] [--kms-key-arn <value>] [--tags <value>] [--zip-file <value>] [--cli-input-json <value>]
带值的命令
aws lambda create-function --function-name "lambdainvoke" --runtime "nodejs8.10" --role "arn:aws:iam::625297745038:role/lambdaapipolicy" --handler "index.handler" --timeout 5 --memory-size 256 --zip-file "fileb://C: odeproject\index.zip"
输出如下所示 −

在 AWS 控制台中创建的函数如下所示 −



现在,您可以使用以下命令调用该函数:invoke
--function-name <value> [--invocation-type <value>] [--log-type <value>] [--client-context <value>] [--payload <value>] [--qualifier <value>] outfile <value>
选项
--function-name − 指定要调用的函数的名称。
--invocation-type(string) − 默认情况下,invokation-type 为 requestresponse。可与 invokation-type 一起使用的值是 RequestResponse、Event 和 DryRun。
Event invocation-type 用于异步响应。
当您想要验证 Lambda 函数而无需执行它时,请使用 DryRun。
--log-type − 如果调用类型为 RequestResponse,它将是 Tail。它提供最后 4KB 的 base64 编码日志数据。可能的值是 Tail 和 None。
--client-context − 您可以将客户端特定的详细信息传递给 Lambda 函数。clientcontext 必须采用 json 格式并采用 base64 编码。最大文件大小为 3583 字节。
--payload − 将 json 格式输入到您的 lambda 函数。
--qualifier − 您可以指定 Lambda 函数版本或别名。如果您传递函数版本,则 api 将使用合格函数 arn 来调用 Lambda 函数。如果指定别名,api 将使用别名 ARN 来调用 Lambda 函数。
outfile − 这是将保存内容的文件名。
带值的命令
aws lambda invoke --function-name "lambdainvoke" --log-type Tail C: odeproject\outputfile.txt

您可以使用 payload 选项以 json 格式向 lambda 函数发送虚拟事件,如下所示。
相关的 AWS Lambda 代码如下 −
exports.handler = async (event, callback) => { console.log("Hello => "+ event.name); console.log("Address =>"+ event.addr); callback(null, 'Hello '+event.name +" and address is "+ event.addr); };
观察代码,我们有控制台event.name和event.addr。现在,让我们使用 aws cli 中的 payload 选项发送带有名称和地址的事件,如下所示 −
aws lambdainvoke --function-name "lambdainvoke" --log-type Tail --payload file://C:\clioutput\input.txt C:\clioutput\outputfile.txt
然后,payload 将输入作为具有 json 输入的文件路径,如下所示 −
{"name":"Roy Singh", "addr":"Mumbai"}
相应的输出如下所示 −

输出存储在文件 C:\clioutput\outputfile.txt 中,如下所示−
"Hello Roy Singh and address is Mumbai"
示例事件
您可以通过传递示例事件来测试 AWS Lambda 函数。本节提供了一些 AWS 服务的示例事件。您可以使用 invoke 命令来测试使用任何服务触发时的输出。请观察下面给出的相应示例事件的代码 −
Amazon S3 Put Sample Event
{ "Records": [{ "eventVersion": "2.0", "eventTime": "1970-01-01T00:00:00.000Z", "requestParameters": { "SourceIPAddress": "127.0.0.1" }, "s3": { "configurationId": "testConfigRule", "object": { "eTag": "0123456789abcdef0123456789abcdef", "sequencer": "0A1B2C3D4E5F678901", "key": "HappyFace.jpg", "size": 1024 }, "bucket": { "arn": bucketarn, "name": "Sourcebucket", "ownerIdentity": { "principalId": "EXAMPLE" } }, "s3SchemaVersion": "1.0" }, "responseElements": { "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH", "x-amz-request-id": "EXAMPLE123456789" }, "awsRegion": "us-east-1", "eventName": "ObjectCreated:Put", "userIdentity": { "principalId": "EXAMPLE" }, "eventSource": "aws:s3" }] }
要从 s3 put 事件中获取文件的详细信息,您可以使用以下命令 −
event.Records[0].s3.object.key //将显示文件的名称
要获取存储桶名称,您可以使用以下命令 −
event.Records[0].s3.bucket.name //将提供存储桶的名称。
要查看 EventName,您可以使用以下命令 −
event.Records[0].eventName //将显示事件名称
Amazon S3 删除示例事件
{ "Records": [{ "eventVersion": "2.0", "eventTime": "1970-01-01T00:00:00.000Z", "requestParameters": { "SourceIPAddress": "127.0.0.1" }, "s3": { "configurationId": "testConfigRule", "object": { "sequencer": "0A1B2C3D4E5F678901", "key": "HappyFace.jpg" }, "bucket": { "arn": bucketarn, "name": "Sourcebucket", "ownerIdentity": { "principalId": "EXAMPLE" } }, "s3SchemaVersion": "1.0" }, "responseElements": { "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH", "x-amz-request-id": "EXAMPLE123456789" }, "awsRegion": "us-east-1", "eventName": "ObjectRemoved:Delete", "userIdentity": { "principalId": "EXAMPLE" }, "eventSource": "aws:s3" }] }
Amazon DynamoDB
当 DynamoDB 表发生更改时,Amazon DynamoDB 可以成为 AWS Lambda 上的事件。我们可以执行添加条目、更新和删除 DynamodDB 表中的记录等操作。
此处显示了 DynamoDB 添加、插入和删除事件的示例事件 −
{ "Records": [{ "eventID": "1", "eventVersion": "1.0", "dynamodb": { "Keys": { "Id": { "N": "101" } }, "NewImage": { "Message": { "S": "New item!" }, "Id": { "N": "101" } }, "StreamViewType": "NEW_AND_OLD_IMAGES", "SequenceNumber": "111", "SizeBytes": 26 }, "awsRegion": "us-west-2", "eventName": "INSERT", "eventSourceARN": eventSourcearn, "eventSource": "aws:dynamodb" }, { "eventID": "2", "eventVersion": "1.0", "dynamodb": { "OldImage": { "Message": { "S": "New item!" }, "Id": { "N": "101" } }, "SequenceNumber": "222", "Keys": { "Id": { "N": "101" } }, "SizeBytes": 59, "NewImage": { "Message": { "S": "This item has changed" }, "Id": { "N": "101" } }, "StreamViewType": "NEW_AND_OLD_IMAGES" }, "awsRegion": "us-west-2", "eventName": "MODIFY", "eventSourceARN": Sourcearn, "eventSource": "aws:dynamodb" }, { "eventID": "3", "eventVersion": "1.0", "dynamodb": { "Keys": { "Id": { "N": "101" } }, "SizeBytes": 38, "SequenceNumber": "333", "OldImage": { "Message": { "S": "This item has changed" }, "Id": { "N": "101" } }, "StreamViewType": "NEW_AND_OLD_IMAGES" }, "awsRegion": "us-west-2", "eventName": "REMOVE", "eventSourceARN": Sourcearn, "eventSource": "aws:dynamodb" }] }
Amazon Simple Notification Service
AWS Lambda 有助于处理在 Simple Notification Service (SNS) 中创建的通知。每当在 SNS 中发布消息时,Lambda 函数都可以通过 SNS 事件触发,该事件包含消息的详细信息。这些消息可以在 Lambda 函数内部处理,并可以根据要求进一步发送到其他服务。
输入消息后,SNS 将触发 Lambda 函数。如果任何错误尝试调用 Lambda 函数,SNS 将重试调用 lambda 函数最多三次。
Amazon SNS 示例事件
下面显示了一个示例事件,其中包含 AWS Lambda 函数中可用的所有详细信息,可用于执行进一步的处理 −
{ "Records": [{ "EventVersion": "1.0", "EventSubscriptionArn": eventsubscriptionarn, "EventSource": "aws:sns", "Sns": { "SignatureVersion": "1", "Timestamp": "1970-01-01T00:00:00.000Z", "Signature": "EXAMPLE", "SigningCertUrl": "EXAMPLE", "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e", "Message": "Hello from SNS!", "MessageAttributes": { "Test": { "Type": "String", "Value": "TestString" }, "TestBinary": { "Type": "Binary", "Value": "TestBinary" } }, "Type": "Notification", "UnsubscribeUrl": "EXAMPLE", "TopicArn": topicarn, "Subject": "TestInvoke" } }] }
Amazon Simple Mail Service
Amazon Simple Mail Service 可用于发送消息,也可用于接收消息。收到消息时,可在 Simple Mail Service 上调用 AWS Lambda 函数。
Amazon SES 电子邮件接收示例事件
在 AWS Lambda 中使用时 SES 事件的详细信息如下所示 −
{ "Records": [{ "eventVersion": "1.0", "ses": { "mail": { "commonHeaders": { "from": [ "Jane Doe <janedoe@example.com>" ], "to": [ "johndoe@Source.com" ], "returnPath": "janedoe@example.com", "messageId": "<0123456789Source.com>", "date": "Wed, 7 Oct 2015 12:34:56 -0700", "subject": "Test Subject" }, "example": "janedoe@example.com", "timestamp": "1970-01-01T00:00:00.000Z", "destination": [ "johndoe@example.com" ], "headers": [{ "name": "Return-Path", "value": "<janedoe@example.com>" }, { "name": "Received", "value": "from mailer.example.com (mailer.example.com [203.0.113.1]) by inbound-smtp.us-west-2.amazonaws.com with SMTP id o3vrnil0e2ic for johndoe@example.com; Wed, 07 Oct 2015 12:34:56 +0000 (UTC)" }, { "name": "DKIM-Signature", "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=example; h=mime-version:from:date:message-id:subject:to:content-type; bh=jX3F0bCAI7sIbkHyy3mLYO28ieDQz2R0P8HwQkklFj4=; b=sQwJ+LMe9RjkesGu+vqU56asvMhrLRRYrWCbV" }, { "name": "MIME-Version", "value": "1.0" }, { "name": "From", "value": "Jane Doe <janedoe@example.com>" }, { "name": "Date", "value": "Wed, 7 Oct 2015 12:34:56 -0700" }, { "name": "Message-ID", "value": "<0123456789example.com>" }, { "name": "Subject", "value": "Test Subject" }, { "name": "To", "value": "johndoe@example.com" }, { "name": "Content-Type", "value": "text/plain; charset=UTF-8" }], "headersTruncated": false, "messageId": "o3vrnil0e2ic28tr" }, "receipt": { "recipients": [ "johndoe@example.com" ], "timestamp": "1970-01-01T00:00:00.000Z", "spamVerdict": { "status": "PASS" }, "dkimVerdict": { "status": "PASS" }, "processingTimeMillis": 574, "action": { "type": "Lambda", "invocationType": "Event", "functionArn": "arn:aws:lambda:us-west-2:012345678912:function:example" }, "spfVerdict": { "status": "PASS" }, "virusVerdict": { "status": "PASS" } } }, "eventexample": "aws:ses" }] }
Amazon Cloudwatch Logs
可以使用 CloudWatch Logs 订阅 从 Amazon CloudWatch Logs 触发 AWS Lambda。CloudWatch Logs 订阅包含有关日志的实时数据,这些数据可以在 AWS Lambda 内部进行处理和分析,也可以用于加载到其他系统。
Amazon CloudWatch Logs 示例事件
{ "awslogs": { "data": "H4sIAAAAAAAAAHWPwQqCQBCGX0Xm7EFtK+smZBEUgXoLCdMhFtKV3akI8d0bLYmibvPPN3wz00CJxmQnTO41whwW QRIctmEcB6sQbFC3CjW3XW8kxpOpP+OC22d1Wml1qZkQGtoMsScxaczKN3plG8zlaHIta5KqWsozoTYw3/djzwhpL wivWFGHGpAFe7DL68JlBUk+l7KSN7tCOEJ4M3/qOI49vMHj+zCKdlFqLaU2ZHV2a4Ct/an0/ivdX8oYc1UVX860fQ DQiMdxRQEAAA==" } }
Amazon API Gateway
可以在 https url 上调用 AWS Lambda 函数。可以在 GET、POST、PUT 上执行此操作。调用 https url 时,也会触发 AWS Lambda 函数,并且使用 get/post 传递到 https 的数据可以在 AWS Lambda 内部使用,以用于插入 DynamoDB 或发送邮件等。
API Gateway 代理请求事件
{ "path": "/test/hello", "headers": { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Encoding": "gzip, deflate, lzma, sdch, br", "Accept-Language": "en-US,en;q=0.8", "CloudFront-Forwarded-Proto": "https", "CloudFront-Is-Desktop-Viewer": "true", "CloudFront-Is-Mobile-Viewer": "false", "CloudFront-Is-SmartTV-Viewer": "false", "CloudFront-Is-Tablet-Viewer": "false", "CloudFront-Viewer-Country": "US", "Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)", "X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==", "X-Forwarded-For": "192.168.100.1, 192.168.1.1", "X-Forwarded-Port": "443", "X-Forwarded-Proto": "https" }, "pathParameters": { "proxy": "hello" }, "requestContext": { "accountId": "123456789012", "reexampleId": "us4z18", "stage": "test", "requestId": "41b45ea3-70b5-11e6-b7bd-69b5aaebc7d9", "identity": { "cognitoIdentityPoolId": "", "accountId": "", "cognitoIdentityId": "", "caller": "", "apiKey": "", "exampleIp": "192.168.100.1", "cognitoAuthenticationType": "", "cognitoAuthenticationProvider": "", "userArn": "", "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "user": "" }, "reexamplePath": "/{proxy+}", "httpMethod": "GET", "apiId": "wt6mne2s9k" }, "reexample": "/{proxy+}", "httpMethod": "GET", "queryStringParameters": { "name": "me" }, "stageVariables": { "stageVarName": "stageVarValue" } }
API 网关代理响应事件
{ "statusCode": 200, "headers": { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Encoding": "gzip, deflate, lzma, sdch, br", "Accept-Language": "en-US,en;q=0.8", "CloudFront-Forwarded-Proto": "https", "CloudFront-Is-Desktop-Viewer": "true", "CloudFront-Is-Mobile-Viewer": "false", "CloudFront-Is-SmartTV-Viewer": "false", "CloudFront-Is-Tablet-Viewer": "false", "CloudFront-Viewer-Country": "US", "Host": "wt6mne2s9k.execute-api.us-west-2.amazonaws.com", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36 OPR/39.0.2256.48", "Via": "1.1 fb7cca60f0ecd82ce07790c9c5eef16c.cloudfront.net (CloudFront)", "X-Amz-Cf-Id": "nBsWBOrSHMgnaROZJK1wGCZ9PcRcSpq_oSXZNQwQ10OTZL4cimZo3g==", "X-Forwarded-For": "192.168.100.1, 192.168.1.1", "X-Forwarded-Port": "443", "X-Forwarded-Proto": "https" }, "body": "Hello World" }