执行和调用Lambda函数

本章将详细介绍执行和调用Lambda函数的过程及其中涉及的步骤.

AWS Lambda执行模型

AWS执行取决于为AWS Lambda Function添加的配置详细信息.创建函数时,会有内存时间分配,用于执行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 :

命令

$ b创建AWS Lambda函数$ b

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:\nodeproject\index.zip"

输出如下所示 :

带值的命令

在AWS控制台中创建的功能如下所示 :


代码输入类型 现有角色

现在,您可以使用以下命令调用该函数:调用

--function-name <value>
[--invocation-type <value>]
[--log-type <value>]
[--client-context <value>]
[--payload <value>]
[--qualifier <value>]
outfile <value>

选项

 -  function-name :  指定要调用的函数的名称.

 - 调用类型(字符串) :  默认情况下,invokation类型为 requestResponse则的.可用于invokation类型的值是 RequestResponse,Event DryRun .

  • 事件调用类型用于异步响应.

  • 要验证Lambda函数时要使用DryRun无需执行它.

 -  log-type :  它将尾巴如果调用类型是RequestResponse.它给出了最后4KB base64编码的日志数据.可能的值为尾部.

 - 客户端上下文&减号; 您可以传递客户端Lambda函数的具体细节. clientcontext必须是json格式和base64编码.最大文件大小为3583字节.

 - 有效负载&减去; json格式输入到lambda函数.

 - 限定符和减号; 您可以指定Lambda函数版本或别名.如果传递函数版本,则api将使用限定函数arn来调用Lambda函数.如果指定了别名,则api使用别名ARN来调用Lambda函数.

outfile :  这是保存内容的文件名.

带值的命令

aws lambda invoke --function-name "lambdainvoke" --log-type 
Tail C:\nodeproject\outputfile.txt


命令值

您可以使用payload选项以json格式向lambda函数发送虚拟事件,如下所示./p>

相关的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 lambda invoke --function-name "lambdainvoke" --log-type 
Tail --payload file://C:\clioutput\input.txt C:\clioutput\outputfile.txt

Thenpayload将输入作为文件路径,其中json输入如图所示 :

{"name":"Roy Singh", "addr":"Mumbai"}

相应的输出如下所示 :

Correspond Output

输出存储在文件 C:\ clioutput \ output.txt 如下 :

"Hello Roy Singh and address is Mumbai"

示例事件

您可以通过传递示例事件来测试AWS Lambda函数.本节提供了AWS Services的一些示例事件.您可以使用 invoke 命令在使用任何服务触发时测试输出.观察为相应的样本事件提供的代码低于 :

Amazon S3 Put Sample事件

{
  "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"    
   }]
}

亚马逊简单通知服务

AWS Lambda可以帮助您处理在简单通知中创建的通知服务(SNS).每当在SNS中发布消息时,可以使用SNS事件触发Lambda函数,该事件具有消息的详细信息.此消息可在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"
      }
   }]
}

亚马逊简单邮件服务

亚马逊简单邮件服务可用于发送邮件和接收邮件.收到消息后,可以在简单邮件服务上调用AWS Lambda函数.

Amazon SES电子邮件接收示例事件

SES事件的详细信息在AWS Lambda中使用时显示在下面 :

{
  "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日志

可以使用 CloudWatch Logs从Amazon CloudWatch Logs触发AWS Lambda订阅的. CloudWatch Logs订阅包含有关日志的数据实时数据,可以在AWS Lambda内部进行处理和分析,也可以用于加载到其他系统.

Amazon CloudWatch日志示例事件

{
   "awslogs": {
      "data": "H4sIAAAAAAAAAHWPwQqCQBCGX0Xm7EFtK+smZBEUgXoLCdMhFtKV3akI8d0bLYmibvPPN3wz00CJxmQnTO41whwW
      QRIctmEcB6sQbFC3CjW3XW8kxpOpP+OC22d1Wml1qZkQGtoMsScxaczKN3plG8zlaHIta5KqWsozoTYw3/djzwhpL
      wivWFGHGpAFe7DL68JlBUk+l7KSN7tCOEJ4M3/qOI49vMHj+zCKdlFqLaU2ZHV2a4Ct/an0/ivdX8oYc1UVX860fQ
      DQiMdxRQEAAA=="
   }
}

亚马逊API网关

可以在https url上调用AWS Lambda函数。 IT可以在GET,POST,PUT上完成。 调用https url时,也会触发AWS Lambda函数,并且可以在AWS Lambda中使用get / post传递给https的数据,以用于在DynamoDB中插入或发送邮件等。

API Gateway Proxy Request Event

{
   "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 Gateway Proxy Response Event

{
   "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"
}