本章將詳細講解 Lambda 函數(shù)的執(zhí)行和調用過程及其涉及的步驟。
免綁卡注冊AWS云賬戶:http://hkonecloud.755800.com/
AWS Lambda 執(zhí)行模型
AWS 執(zhí)行取決于為 AWS Lambda 函數(shù)添加的配置詳細信息。在創(chuàng)建函數(shù)時,有一個 內存和 分配的時間,用于執(zhí)行 AWS Lambda 函數(shù)。
借助配置詳細信息,AWS Lambda 創(chuàng)建了一個執(zhí)行上下文。執(zhí)行上下文是一個臨時的運行時環(huán)境,它準備好任何外部依賴項,例如數(shù)據(jù)庫連接、http 端點、第三方庫等(如果有)。
當?shù)谝淮握{用 AWS Lambda 函數(shù)或更新 lambda 函數(shù)時,由于執(zhí)行上下文設置,幾乎不會增加延遲。但是,與第一個調用相比,后續(xù)調用更快。如果調用 Lambda 函數(shù)的時間較短,AWS Lambda 會嘗試再次重用執(zhí)行上下文。
執(zhí)行上下文的重用具有以下含義-
如果為執(zhí)行 Lambda 完成了任何數(shù)據(jù)庫連接,則會維護該連接以供重用。因此,Lambda 代碼必須首先檢查連接-如果存在并重用;否則我們將不得不建立新的連接。執(zhí)行上下文在 /tmp 目錄中維護了 500MB 的磁盤空間。所需的數(shù)據(jù)緩存在此目錄中。您可以在代碼中進行額外檢查以查看數(shù)據(jù)是否存在。如果調用 Lambda 函數(shù)時回調或某些后臺處理未完成,則再次調用 lambda 函數(shù)時將開始執(zhí)行。如果您不需要這樣的事情發(fā)生,請確保您的流程在函數(shù)執(zhí)行完成后全部正確結束。
您應該使用執(zhí)行上下文和存儲在 tmp 目錄中的數(shù)據(jù)。在創(chuàng)建新數(shù)據(jù)之前,您必須在代碼中添加必要的檢查以查看所需數(shù)據(jù)是否存在。這將節(jié)省執(zhí)行過程中的時間并使其更快。
我們可以使用 aws cli 手動調用 AWS。我們已經了解了如何使用 cli 創(chuàng)建和部署 AWS Lambda。在這里,我們將首先使用 aws cli 創(chuàng)建一個函數(shù)并調用它。
您可以使用以下命令通過 aws cli-
創(chuàng)建 AWS Lambda 函數(shù)
命令
create-function --function-name--runtime--role--handler[--code] [--description] [--timeout] [--memory-size] [--environment] [--kms-key-arn] [--tags] [--zip-file] [--cli-input-json]
帶值的命令
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 控制臺中創(chuàng)建的函數(shù)如下圖所示-
現(xiàn)在,您可以使用以下命令調用該函數(shù): invoke
--function-name[--invocation-type] [--log-type] [--client-context] [--payload] [--qualifier] outfile
選項
--function-name- 指定要調用的函數(shù)的名稱。
--invocation-type(string)- 默認情況下,調用類型是 requestresponse??捎糜?invokation-type 的值為 RequestResponse、Event 和 DryRun。
事件調用類型將用于異步響應。當您想驗證 Lambda 函數(shù)而不需要執(zhí)行它時,可以使用 DryRun。
--log-type ? 如果調用類型是 RequestResponse,它將是 Tail。它給出了最后 4KB base64 編碼的日志數(shù)據(jù)。可能的值為 Tail 和 None。
--client-context- 您可以將特定于客戶端的詳細信息傳遞給 Lambda 函數(shù)。客戶端上下文必須采用 json 格式和 base64 編碼。最大文件大小為 3583 字節(jié)。
--payload- json 格式輸入到您的 lambda 函數(shù)。
--qualifier- 您可以指定 Lambda 函數(shù)版本或別名。如果您傳遞函數(shù)版本,則 api 將使用限定的函數(shù) arn 來調用 Lambda 函數(shù)。如果您指定別名,api 將使用別名 ARN 來調用 Lambda 函數(shù)。
outfile ? 這是保存內容的文件名。
帶值的命令
aws lambda invoke--function-name "lambdainvoke"--log-type Tail C:\nodeproject\outputfile.txt
您可以使用 payload 選項以如下所示的 json 格式將虛擬事件發(fā)送到 lambda 函數(shù)。
相關的 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?,F(xiàn)在,讓我們使用 aws cli 中的 payload 選項發(fā)送具有名稱和地址的事件,如下所示-
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"}
對應的輸出如下圖-
輸出存儲在文件 C:\clioutput\outputfile.txt 中,如下所示-
"Hello Roy Singh and address is Mumbai"
您可以通過傳遞示例事件來測試 AWS Lambda 函數(shù)。本節(jié)提供了 AWS 服務的一些示例事件。當任何服務觸發(fā)時,您可以使用 invoke 命令來測試輸出。觀察下面為相應示例事件給出的代碼-
{ "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 //will display the name of the file
要 獲取存儲桶名稱,您可以使用以下命令-
event.Records[0].s3.bucket.name //will give the name of the bucket.
要 查看事件名稱,您可以使用以下命令-
event.Records[0].eventName // will display the eventname
{ "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" }] }
當對 DynamoDB 表進行更改時,Amazon DynamoDB 可以成為 AWS Lambda 上的事件。我們可以在DynamodDB表中執(zhí)行添加條目、更新和刪除記錄等操作。
此處顯示了 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) 中創(chuàng)建的通知。每當在 SNS 中發(fā)布消息時,Lambda 函數(shù)都可以通過 SNS 事件觸發(fā),其中包含消息的詳細信息。這些消息可以在 Lambda 函數(shù)內部進行處理,并且可以根據(jù)需要進一步發(fā)送到其他服務。
消息輸入后,SNS 會觸發(fā) Lambda 函數(shù)。如果任何錯誤嘗試調用 Lambda 函數(shù),SNS 將重試調用 lambda 函數(shù)最多 3 次。
具有 AWS Lambda 函數(shù)中可用的所有詳細信息以執(zhí)行進一步過程的示例事件如下所示-
{ "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 可用于發(fā)送消息和接收消息。收到消息后,可以在 Simple Mail Service 上調用 AWS Lambda 函數(shù)。
在 AWS Lambda 中使用 SES 事件的詳細信息如下所示-
{ "Records": [{ "eventVersion": "1.0", "ses": { "mail": { "commonHeaders": { "from": [ "Jane Doe" ], "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": " " }, { "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 " }, { "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" }] }
AWS Lambda 可以使用 CloudWatch Logs 訂閱從 Amazon CloudWatch Logs 觸發(fā)。 CloudWatch Logs 訂閱具有有關日志的實時數(shù)據(jù),這些數(shù)據(jù)可以在 AWS Lambda 內部進行處理和分析,也可以用于加載到其他系統(tǒng)。
{ "awslogs": { "data": "H4sIAAAAAAAAAHWPwQqCQBCGX0Xm7EFtK+smZBEUgXoLCdMhFtKV3akI8d0bLYmibvPPN3wz00CJxmQnTO41whwW QRIctmEcB6sQbFC3CjW3XW8kxpOpP+OC22d1Wml1qZkQGtoMsScxaczKN3plG8zlaHIta5KqWsozoTYw3/djzwhpL wivWFGHGpAFe7DL68JlBUk+l7KSN7tCOEJ4M3/qOI49vMHj+zCKdlFqLaU2ZHV2a4Ct/an0/ivdX8oYc1UVX860fQ DQiMdxRQEAAA==" } }
AWS Lambda 函數(shù)可以在 https url 上調用。它可以在 GET、POST、PUT 上完成。當 https url 被調用時,AWS Lambda 函數(shù)也會被觸發(fā),使用 get/post 傳遞給 https 的數(shù)據(jù)可以在 AWS Lambda 內部可用,用于插入 DynamoDB 或發(fā)送郵件等。
{ "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" } }
{ "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" }
海外服務器免費測試:http://hbjsdrq.com/