本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
教學課程:搭配 Amazon SQS 使用 Lambda
在本教學課程中,您會建立使用來自 Amazon Simple Queue Service (Amazon SQS) 佇列訊息的 Lambda 事件函數。Lambda 事件函數會在將新訊息新增至佇列時執行。函數會將訊息寫入 Amazon CloudWatch Logs 串流。下圖顯示可用來完成教學課程的 AWS 資源。
請執行下列步驟以完成本教學課程:
-
建立將訊息寫入 CloudWatch Logs 的 Lambda 事件函數。
-
建立 Amazon SQS 佇列。
-
建立 Lambda 事件來源映射。事件來源映射會讀取 Amazon SQS 佇列,並在新增訊息時叫用您的 Lambda 事件函數。
-
透過將訊息新增至佇列並監控 CloudWatch Logs 中的結果來測試設定。
先決條件
如果您尚未安裝 AWS Command Line Interface,請依照安裝或更新最新版本的 AWS CLI中的步驟進行安裝。
本教學課程需使用命令列終端機或 Shell 來執行命令。在 Linux 和 macOS 中,使用您偏好的 Shell 和套件管理工具。
在 Windows 中,作業系統的內建終端不支援您常與 Lambda 搭配使用的某些 Bash CLI 命令 (例如 zip)。若要取得 Ubuntu 和 Bash 的 Windows 整合版本,請安裝適用於 Linux 的 Windows 子系統。
建立執行角色
執行角色是 AWS Identity and Access Management (IAM) 角色,授予 Lambda 事件函數存取 AWS 服務 和資源的許可。若要允許函數從 Amazon SQS 中讀取項目,請連接 AWSLambdaSQSQueueExecutionRole 許可政策。
建立執行角色並連接 Amazon SQS 許可政策
-
開啟 IAM 主控台中的角色頁面。
-
選擇 建立角色。
-
針對信任的實體類型,請選擇 AWS 服務。
-
針對使用案例,請選擇 Lambda。
-
選擇下一步。
-
在許可政策搜尋方塊中,輸入 AWSLambdaSQSQueueExecutionRole。
-
選取 AWSLambdaSQSQueueExecutionRole 政策,然後選擇下一步。
-
針對角色詳細資訊下的角色名稱,請輸入 lambda-sqs-role,然後選擇建立角色。
角色建立後,請記下執行角色的 Amazon Resource Name (ARN)。在後續步驟中會需要用到它。
建立事件函數
建立處理 Amazon SQS 訊息的 Lambda 事件函數。函數程式碼會將 Amazon SQS 的訊息內文記錄到 Amazon CloudWatch Logs。
本教學課程使用 Node.js 24 執行時間,但我們也提供其他執行時間語言的範例程式碼。您可以在下列方塊中選取索引標籤,查看您感興趣的執行期程式碼。此步驟要使用的 JavaScript 程式碼,位於 JavaScript 索引標籤中顯示的第一個範例。
- .NET
-
- 適用於 .NET 的 SDK
-
GitHub 上提供更多範例。尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。
使用 .NET 搭配 Lambda 來使用 SQS 事件。
// 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 for 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
-
- 適用於 JavaScript (v3) 的 SDK
-
GitHub 上提供更多範例。尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。
使用 JavaScript 搭配 Lambda 來使用 SQS 事件。
// 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;
}
}
使用 TypeScript 搭配 Lambda 來使用 SQS 事件。
// 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 上提供更多範例。尋找完整範例,並了解如何在無伺服器範例儲存庫中設定和執行。
使用 PHP 搭配 Lambda 來使用 SQS 事件。
// 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
-
- 適用於 Python 的 SDK (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 for 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
-
- 適用於 Rust 的 SDK
-
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 事件函數
-
建立專案的目錄,然後切換至該目錄。
mkdir sqs-tutorial
cd sqs-tutorial
-
將範例 JavaScript 程式碼複製到名為 index.js 的新檔案。
-
使用以下 zip 命令建立部署套件。
zip function.zip index.js
-
使用 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 nodejs24.x \
--role arn:aws:iam::111122223333:role/lambda-sqs-role
測試事件函數
使用 invoke AWS CLI 命令和範例 Amazon SQS 事件手動叫用 Lambda 事件函數。
使用範例事件叫用 Lambda 事件函數
-
將下面的 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"
}
]
}
-
執行下列叫用 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 支援的全域命令列選項。
-
在回應中查找 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
建立 Lambda 事件函數可用作事件來源的 Amazon SQS 佇列。Lambda 事件函數和 Amazon SQS 佇列必須位於相同的 中 AWS 區域。
建立佇列後,請記下其 ARN。當您將佇列與 Lambda 事件函數建立關聯時,在下一個步驟中需要此操作。
設定事件來源
建立事件來源映射,將 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
傳送測試訊息
將 Amazon SQS 訊息傳送至 Lambda 事件函數
-
開啟 Amazon SQS 主控台。
-
選擇您稍早建立的佇列。
-
選擇傳送及接收訊息。
-
在訊息內文下,輸入測試訊息,例如「這是測試訊息」。
-
選擇傳送訊息。
Lambda 輪詢佇列以查看是否有更新。當有新訊息時,Lambda 會使用佇列中的此新事件資料來叫用您的函數。如果函數處理常式傳回而無例外情況,則 Lambda 會認為訊息已成功處理,並開始讀取佇列中的新訊息。成功處理訊息之後,Lambda 從佇列中自動刪除它。如果處理常式擲出例外情況,Lambda 會認為訊息批次未成功處理,並且 Lambda 會調用具有相同訊息批次的函數。
檢查 CloudWatch 日誌
確認事件函數已處理訊息
開啟 Lambda 主控台的事件函數頁面。
-
選擇 ProcessSQSRecord 函數。
-
選擇監控。
-
選擇檢視 CloudWatch 日誌。
-
在 CloudWatch 主控台中,選擇函數的日誌串流。
-
查找 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 帳戶。
刪除執行角色
-
開啟 IAM 主控台中的 角色頁面 。
-
選取您建立的執行角色。
-
選擇刪除。
-
在文字輸入欄位中輸入角色的名稱,然後選擇刪除。
刪除 Lambda 事件函數
-
開啟 Lambda 主控台的事件函數頁面。
-
選取您建立的事件函數。
-
選擇 動作、刪除。
-
在文字輸入欄位中輸入 confirm,然後選擇 刪除 。