教學課程:搭配 Amazon 使用 Lambda SQS - AWS Lambda

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

教學課程:搭配 Amazon 使用 Lambda SQS

在本教學課程中,您會建立 Lambda 函數,以使用來自 Amazon Simple Queue Service (Amazon SQS) 佇列的訊息。只要有新訊息加入佇列,Lambda 函數就會執行。函數會將訊息寫入 Amazon CloudWatch Logs 串流。下圖顯示可用來完成教學課程的 AWS 資源。

顯示 Amazon SQS 訊息、Lambda 函數和 CloudWatch Logs 串流的圖表

請執行下列步驟以完成本教學課程:

  1. 建立將訊息寫入 CloudWatch 日誌的 Lambda 函數。

  2. 建立 Amazon SQS佇列。

  3. 建立 Lambda 事件來源映射。事件來源映射會讀取 Amazon SQS佇列,並在新增訊息時叫用 Lambda 函數。

  4. 將訊息新增至佇列並監控 CloudWatch Logs 中的結果,以測試設定。

必要條件

如果您沒有 AWS 帳戶,請完成下列步驟以建立 。

若要註冊 AWS 帳戶
  1. 開啟https://portal.aws.amazon.com/billing/註冊

  2. 請遵循線上指示進行。

    部分註冊程序需接收來電,並在電話鍵盤輸入驗證碼。

    當您註冊 時 AWS 帳戶,AWS 帳戶根使用者會建立 。根使用者有權存取該帳戶中的所有 AWS 服務 和資源。作為安全最佳實務,請將管理存取權指派給使用者,並且僅使用根使用者來執行需要根使用者存取權的任務

AWS 會在註冊程序完成後傳送確認電子郵件給您。您可以隨時前往 https://aws.amazon.com/ 並選擇我的帳戶 來檢視目前的帳戶活動和管理您的帳戶

註冊 後 AWS 帳戶,請保護 AWS 帳戶根使用者、啟用 AWS IAM Identity Center並建立管理使用者,以免將根使用者用於日常任務。

保護您的 AWS 帳戶根使用者
  1. 選擇根使用者並輸入 AWS 帳戶 您的電子郵件地址,以帳戶擁有者AWS Management Console身分登入 。在下一頁中,輸入您的密碼。

    如需使用根使用者登入的說明,請參閱 AWS 登入 使用者指南中的以根使用者身分登入

  2. 為您的根使用者開啟多重要素驗證 (MFA)。

    如需指示,請參閱 IAM 使用者指南 中的為您的 AWS 帳戶 根使用者 (主控台) 啟用虛擬MFA裝置

建立具有管理存取權的使用者
  1. 啟用IAM身分中心。

    如需指示,請參閱 AWS IAM Identity Center 使用者指南中的啟用 AWS IAM Identity Center

  2. 在 IAM Identity Center 中,將管理存取權授予使用者。

    如需使用 IAM Identity Center 目錄 作為身分來源的教學課程,請參閱 AWS IAM Identity Center 使用者指南 中的使用預設值設定使用者存取權 IAM Identity Center 目錄

以具有管理存取權的使用者身分登入
  • 若要使用 IAM Identity Center 使用者登入,請使用您建立 IAM Identity Center 使用者時URL傳送到您電子郵件地址的登入。

    如需使用 IAM Identity Center 使用者登入的協助,請參閱 AWS 登入 使用者指南 中的登入 AWS 存取入口網站

指派存取權給其他使用者
  1. 在 IAM Identity Center 中,建立遵循套用最低權限許可最佳實務的許可集。

    如需指示,請參閱《AWS IAM Identity Center 使用者指南》中的建立許可集

  2. 將使用者指派至群組,然後對該群組指派單一登入存取權。

    如需指示,請參閱《AWS IAM Identity Center 使用者指南》中的新增群組

如果您尚未安裝 AWS Command Line Interface,請依照安裝或更新最新版本 AWS CLI的步驟進行安裝。

本教學課程需使用命令列終端機或 Shell 來執行命令。在 Linux 和 macOS 中,使用您偏好的 Shell 和套件管理工具。

注意

在 Windows 中,作業系統的內建終端機不支援您常與 Lambda 搭配使用的某些 Bash CLI命令 (例如 zip)。若要取得 Ubuntu 和 Bash 的 Windows 整合版本,請安裝適用於 Linux 的 Windows 子系統

建立執行角色

步驟 1:建立執行角色

執行角色是 AWS Identity and Access Management (IAM) 角色,授予 Lambda 函數存取 AWS 服務和資源的許可。若要允許函數從 Amazon 讀取項目SQS,請連接AWSLambdaSQSQueueExecutionRole許可政策。

建立執行角色並連接 Amazon SQS許可政策
  1. 開啟IAM主控台的角色頁面

  2. 選擇建立角色

  3. 針對信任的實體類型,請選擇 AWS 服務

  4. 針對使用案例,請選擇 Lambda

  5. 選擇 Next (下一步)

  6. 許可政策搜尋方塊中,輸入 AWSLambdaSQSQueueExecutionRole

  7. 選取AWSLambdaSQSQueueExecutionRole政策,然後選擇下一步。

  8. 針對角色詳細資訊下的角色名稱,請輸入 lambda-sqs-role,然後選擇建立角色

建立角色後,記下執行角色的 Amazon Resource Name (ARN)。在後續步驟中會需要用到它。

建立函數

步驟 2:建立 Lambda 函數

建立 Lambda 函數以處理您的 Amazon SQS 訊息。函數程式碼會將 Amazon SQS 訊息的內文記錄到 CloudWatch Logs。

本教學課程使用 Node.js 18.x 執行期,但我們也有提供其他執行期語言的範例程式碼。您可以在下列方塊中選取索引標籤,查看您感興趣的執行期程式碼。您將在此步驟中使用的 JavaScript 程式碼位於JavaScript索引標籤中顯示的第一個範例。

.NET
AWS SDK for .NET
注意

還有更多 。 GitHub尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。

使用 使用 Lambda 取用SQS事件NET。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 using Amazon.Lambda.Core; using Amazon.Lambda.SQSEvents; // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] namespace SqsIntegrationSampleCode { public async Task FunctionHandler(SQSEvent evnt, ILambdaContext context) { foreach (var message in evnt.Records) { await ProcessMessageAsync(message, context); } context.Logger.LogInformation("done"); } private async Task ProcessMessageAsync(SQSEvent.SQSMessage message, ILambdaContext context) { try { context.Logger.LogInformation($"Processed message {message.Body}"); // TODO: Do interesting work based on the new message await Task.CompletedTask; } catch (Exception e) { //You can use Dead Letter Queue to handle failures. By configuring a Lambda DLQ. context.Logger.LogError($"An error occurred"); throw; } } }
Go
SDK for Go V2
注意

還有更多 。 GitHub尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。

使用 Go 使用 Lambda 取用SQS事件。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package integration_sqs_to_lambda import ( "fmt" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ) func handler(event events.SQSEvent) error { for _, record := range event.Records { err := processMessage(record) if err != nil { return err } } fmt.Println("done") return nil } func processMessage(record events.SQSMessage) error { fmt.Printf("Processed message %s\n", record.Body) // TODO: Do interesting work based on the new message return nil } func main() { lambda.Start(handler) }
Java
SDK 適用於 Java 2.x
注意

還有更多 。 GitHub尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。

使用 Java 搭配 Lambda 使用SQS事件。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import com.amazonaws.services.lambda.runtime.events.SQSEvent; import com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage; public class Function implements RequestHandler<SQSEvent, Void> { @Override public Void handleRequest(SQSEvent sqsEvent, Context context) { for (SQSMessage msg : sqsEvent.getRecords()) { processMessage(msg, context); } context.getLogger().log("done"); return null; } private void processMessage(SQSMessage msg, Context context) { try { context.getLogger().log("Processed message " + msg.getBody()); // TODO: Do interesting work based on the new message } catch (Exception e) { context.getLogger().log("An error occurred"); throw e; } } }
JavaScript
SDK 適用於 JavaScript (v3)
注意

還有更多 。 GitHub尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。

使用 使用 Lambda 取用SQS事件 JavaScript。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 exports.handler = async (event, context) => { for (const message of event.Records) { await processMessageAsync(message); } console.info("done"); }; async function processMessageAsync(message) { try { console.log(`Processed message ${message.body}`); // TODO: Do interesting work based on the new message await Promise.resolve(1); //Placeholder for actual async work } catch (err) { console.error("An error occurred"); throw err; } }

使用 使用 Lambda 取用SQS事件 TypeScript。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import { SQSEvent, Context, SQSHandler, SQSRecord } from "aws-lambda"; export const functionHandler: SQSHandler = async ( event: SQSEvent, context: Context ): Promise<void> => { for (const message of event.Records) { await processMessageAsync(message); } console.info("done"); }; async function processMessageAsync(message: SQSRecord): Promise<any> { try { console.log(`Processed message ${message.body}`); // TODO: Do interesting work based on the new message await Promise.resolve(1); //Placeholder for actual async work } catch (err) { console.error("An error occurred"); throw err; } }
PHP
適用於 PHP 的 SDK
注意

還有更多 。 GitHub尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。

使用 使用 Lambda 取用SQS事件PHP。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 <?php # using bref/bref and bref/logger for simplicity use Bref\Context\Context; use Bref\Event\InvalidLambdaEvent; use Bref\Event\Sqs\SqsEvent; use Bref\Event\Sqs\SqsHandler; use Bref\Logger\StderrLogger; require __DIR__ . '/vendor/autoload.php'; class Handler extends SqsHandler { private StderrLogger $logger; public function __construct(StderrLogger $logger) { $this->logger = $logger; } /** * @throws InvalidLambdaEvent */ public function handleSqs(SqsEvent $event, Context $context): void { foreach ($event->getRecords() as $record) { $body = $record->getBody(); // TODO: Do interesting work based on the new message } } } $logger = new StderrLogger(); return new Handler($logger);
Python
SDK for Python (Boto3)
注意

還有更多 。 GitHub尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。

使用 Python 使用 Lambda 取用SQS事件。

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 def lambda_handler(event, context): for message in event['Records']: process_message(message) print("done") def process_message(message): try: print(f"Processed message {message['body']}") # TODO: Do interesting work based on the new message except Exception as err: print("An error occurred") raise err
Ruby
SDK 適用於 Ruby
注意

還有更多 。 GitHub尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。

使用 Ruby 使用 Lambda 來取用SQS事件。

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 def lambda_handler(event:, context:) event['Records'].each do |message| process_message(message) end puts "done" end def process_message(message) begin puts "Processed message #{message['body']}" # TODO: Do interesting work based on the new message rescue StandardError => err puts "An error occurred" raise err end end
Rust
SDK for Rust
注意

還有更多 。 GitHub尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。

使用 Rust 使用 Lambda 取用SQS事件。

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 use aws_lambda_events::event::sqs::SqsEvent; use lambda_runtime::{run, service_fn, Error, LambdaEvent}; async fn function_handler(event: LambdaEvent<SqsEvent>) -> Result<(), Error> { event.payload.records.iter().for_each(|record| { // process the record tracing::info!("Message body: {}", record.body.as_deref().unwrap_or_default()) }); Ok(()) } #[tokio::main] async fn main() -> Result<(), Error> { tracing_subscriber::fmt() .with_max_level(tracing::Level::INFO) // disable printing the name of the module in every log line. .with_target(false) // disabling time is handy because CloudWatch will add the ingestion time. .without_time() .init(); run(service_fn(function_handler)).await }
若要建立 Node.js Lambda 函數
  1. 建立專案的目錄,然後切換至該目錄。

    mkdir sqs-tutorial cd sqs-tutorial
  2. 將範例 JavaScript 程式碼複製到名為 的新檔案中index.js

  3. 使用以下 zip 命令建立部署套件。

    zip function.zip index.js
  4. 使用 create-function AWS CLI 命令建立 Lambda 函數。針對 role 參數,輸入您先前建立之執行角色ARN的 。

    注意

    Lambda 函數和 Amazon SQS佇列必須位於相同的 中 AWS 區域。

    aws lambda create-function --function-name ProcessSQSRecord \ --zip-file fileb://function.zip --handler index.handler --runtime nodejs18.x \ --role arn:aws:iam::111122223333:role/lambda-sqs-role

測試函數

步驟 3:測試 Lambda 函數

使用 invoke AWS CLI 命令和範例 Amazon SQS事件手動叫用 Lambda 函數。

使用範例事件調用 Lambda 函數
  1. 將下列項目儲存JSON為名為 的檔案input.json。這會JSON模擬 Amazon SQS可能傳送至 Lambda 函數的事件,其中 "body"包含來自佇列的實際訊息。在此範例中,訊息為 "test"

    範例 Amazon SQS事件

    這是測試事件,您不需要變更訊息或帳號。

    { "Records": [ { "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d", "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", "body": "test", "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1545082649183", "SenderId": "AIDAIENQZJOLO23YVJ4VO", "ApproximateFirstReceiveTimestamp": "1545082649185" }, "messageAttributes": {}, "md5OfBody": "098f6bcd4621d373cade4e832627b4f6", "eventSource": "aws:sqs", "eventSourceARN": "arn:aws:sqs:us-east-1:111122223333:my-queue", "awsRegion": "us-east-1" } ] }
  2. 執行下列叫用 AWS CLI 命令。此命令會在回應中傳回 CloudWatch 日誌。如需擷取日誌的詳細資訊,請參閱使用存取記錄 AWS CLI

    aws lambda invoke --function-name ProcessSQSRecord --payload file://input.json out --log-type Tail \ --query 'LogResult' --output text --cli-binary-format raw-in-base64-out | base64 --decode

    如果您使用的是 第 2 AWS CLI 版,則需要 cli-binary-format選項。若要讓此成為預設的設定,請執行 aws configure set cli-binary-format raw-in-base64-out。若要取得更多資訊,請參閱《AWS Command Line Interface 使用者指南第 2 版》AWS CLI 支援的全域命令列選項

  3. 在回應中查找 INFO 日誌。這是 Lambda 函數記錄訊息內文的位置。您應該會看到類似以下內容的輸出:

    2023-09-11T22:45:04.271Z 348529ce-2211-4222-9099-59d07d837b60 INFO Processed message test 2023-09-11T22:45:04.288Z 348529ce-2211-4222-9099-59d07d837b60 INFO done

建立 Amazon SQS佇列

步驟 4 建立 Amazon SQS佇列

建立 Amazon SQS佇列,讓 Lambda 函數可以用作事件來源。Lambda 函數和 Amazon SQS佇列必須位於相同的 中 AWS 區域。

建立佇列
  1. 開啟 Amazon SQS主控台

  2. 選擇建立佇列

  3. 輸入佇列的名稱。將所有其他選項保留為預設值。

  4. 選擇建立佇列

建立佇列後,記下其 ARN。在下個步驟中,將佇列與您的 Lambda 函數建立關聯時會需要用到它。

設定事件來源

步驟 5:設定事件來源映射

透過建立事件來源映射 ,將 Amazon SQS佇列連接至 Lambda 函數。 Lambda 如何處理來自串流和佇列型事件來源的記錄事件來源映射會讀取 Amazon SQS佇列,並在新增訊息時叫用 Lambda 函數。

若要在 Amazon SQS佇列和 Lambda 函數之間建立映射,請使用 create-event-source-mapping AWS CLI 命令。範例:

aws lambda create-event-source-mapping --function-name ProcessSQSRecord --batch-size 10 \ --event-source-arn arn:aws:sqs:us-east-1:111122223333:my-queue

若要取得事件來源映射的清單,請使用 list-event-source-mappings命令。範例:

aws lambda list-event-source-mappings --function-name ProcessSQSRecord

傳送測試訊息

步驟 6:傳送測試訊息
將 Amazon SQS 訊息傳送至 Lambda 函數
  1. 開啟 Amazon SQS主控台

  2. 選擇您稍早建立的佇列。

  3. 選擇傳送及接收訊息

  4. 訊息內文下,輸入測試訊息,例如「這是測試訊息」。

  5. 選擇 傳送訊息

Lambda 輪詢佇列以查看是否有更新。當有新訊息時,Lambda 會使用佇列中的此新事件資料來叫用您的函數。如果函數處理常式傳回而無例外情況,則 Lambda 會認為訊息已成功處理,並開始讀取佇列中的新訊息。成功處理訊息之後,Lambda 從佇列中自動刪除它。如果處理常式擲出例外情況,Lambda 會認為訊息批次未成功處理,並且 Lambda 會調用具有相同訊息批次的函數。

檢查 CloudWatch 日誌

步驟 6:傳送測試訊息
確認函數已處理訊息
  1. 開啟 Lambda 主控台中的函數頁面

  2. 選擇 ProcessSQSRecord 函數。

  3. 選擇 監控

  4. 選擇 檢視 CloudWatch 日誌

  5. 在 CloudWatch 主控台中,選擇函數的日誌串流

  6. 查找 INFO 日誌。這是 Lambda 函數記錄訊息內文的位置。您應該會看到您從 Amazon SQS佇列傳送的訊息。範例:

    2023-09-11T22:49:12.730Z b0c41e9c-0556-5a8b-af83-43e59efeec71 INFO Processed message this is a test message.

清除您的資源

除非您想要保留為此教學課程建立的資源,否則您現在便可刪除。透過刪除不再使用 AWS 的資源,您可以避免不必要的 費用 AWS 帳戶。

刪除執行角色
  1. 開啟IAM主控台的角色頁面

  2. 選取您建立的執行角色。

  3. 選擇 刪除

  4. 在文字輸入欄位中輸入角色的名稱,然後選擇 刪除

若要刪除 Lambda 函數
  1. 開啟 Lambda 主控台中的 函數頁面

  2. 選擇您建立的函數。

  3. 選擇 Actions (動作)、Delete (刪除)。

  4. 在文字輸入欄位中輸入 delete,然後選擇 刪除

若要刪除 Amazon SQS佇列
  1. 登入 AWS Management Console 並在 開啟 Amazon SQS主控台https://console.aws.amazon.com/sqs/

  2. 選取您建立的佇列。

  3. 選擇 刪除

  4. 在文字輸入欄位中輸入 confirm

  5. 選擇 刪除