

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

# 搭配 Amazon SQS 使用 Lambda
<a name="with-sqs"></a>

**注意**  
如要將資料傳送到 Lambda 函數以外的目標，或在傳送資料之前讓資料更豐富，請參閱 [Amazon EventBridge Pipes](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-pipes.html)。

您可以使用 Lambda 函數處理 Amazon Simple Queue Service (Amazon SQS) 佇列中的訊息。Lambda [事件來源映射](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/standard-queues.html)既支援[標準佇列](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html)，也支援[先進先出 (FIFO) 佇列](invocation-eventsourcemapping.md)。您也可以使用佈建模式為 Amazon SQS 事件來源映射配置專用輪詢資源。Lambda 函數和 Amazon SQS 佇列必須位於相同的 中 AWS 區域，雖然它們可以位於[不同的 AWS 帳戶](with-sqs-cross-account-example.md) 中。

處理 Amazon SQS 訊息時，您需要實作部分批次回應邏輯，避免批次中部分訊息處理失敗時，已成功處理的訊息被重新執行。Powertools for 的 [Batch Processor 公用程式](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/)可自動處理部分批次回應邏輯、縮短開發時間並改善可靠性，藉此 AWS Lambda 簡化此實作。

**Topics**
+ [了解 Amazon SQS 事件來源映射的輪詢和批次處理行為](#sqs-polling-behavior)
+ [搭配 Amazon SQS 事件來源映射使用佈建模式](#sqs-provisioned-mode)
+ [設定 Amazon SQS 事件來源映射的佈建模式](#sqs-configuring-provisioned-mode)
+ [標準佇列訊息事件範例](#example-standard-queue-message-event)
+ [FIFO 佇列訊息事件範例](#sample-fifo-queues-message-event)
+ [建立和設定 Amazon SQS 事件來源映射](services-sqs-configure.md)
+ [設定 SQS 事件來源映射的擴展行為](services-sqs-scaling.md)
+ [在 Lambda 中處理 SQS 事件來源的錯誤](services-sqs-errorhandling.md)
+ [Amazon SQS 事件來源映射的 Lambda 參數](services-sqs-parameters.md)
+ [對 Amazon SQS 事件來源使用事件篩選](with-sqs-filtering.md)
+ [教學課程：搭配 Amazon SQS 使用 Lambda](with-sqs-example.md)
+ [教學課程：使用跨帳戶 Amazon SQS 佇列做為事件來源](with-sqs-cross-account-example.md)

## 了解 Amazon SQS 事件來源映射的輪詢和批次處理行為
<a name="sqs-polling-behavior"></a>

使用 Amazon SQS 事件來源映射時，Lambda 會輪詢佇列，並在出現事件時[同步](invocation-sync.md)調用函數。每個事件可以包含佇列中的一批訊息。Lambda 一次接收一個批次的這些事件，並為每個批次調用函數一次。當您的函數成功處理批次時，Lambda 會從佇列中刪除其訊息。

當 Lambda 接收到一個批次時，訊息會留在佇列中，但是在佇列的[可見性逾時](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html)期間會變成隱藏。如果您的函數成功處理批次中的全部訊息，Lambda 會從佇列中刪除訊息。根據預設，如果函數在處理批次時遇到錯誤，則該批次中的所有訊息會在可見性逾時時間到了之後再次顯示在佇列中。因此，您的函數程式碼必須能夠多次處理相同的訊息，而不會產生副作用。

**警告**  
Lambda 事件來源映射至少會處理每個事件一次，而且可能會重複處理記錄。為避免與重複事件相關的潛在問題，強烈建議您讓函數程式碼具有等冪性。若要進一步了解，請參閱 AWS 知識中心中的[如何使 Lambda 函數具有等冪性](https://repost.aws/knowledge-center/lambda-function-idempotent)。

若要防止 Lambda 多次處理訊息，您可以設定事件來源映射，在函數回應中包含[批次項目失敗](services-sqs-errorhandling.md#services-sqs-batchfailurereporting)，或者可以使用 [DeleteMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_DeleteMessage.html) API 動作，在 Lambda 函數成功處理訊息時從佇列中移除訊息。

如需 Lambda 支援用於 SQS 事件來源映射的組態參數的詳細資訊，請參閱[建立 SQS 事件來源映射](services-sqs-configure.md#events-sqs-eventsource)。

## 搭配 Amazon SQS 事件來源映射使用佈建模式
<a name="sqs-provisioned-mode"></a>

對於您需要微調事件來源映射輸送量的工作負載，可以使用佈建模式。在佈建模式中，可以定義佈建的事件輪詢器數量的下限和上限。這些佈建的事件輪詢器專用於您的事件來源映射，並且可以透過回應性自動擴展處理意外的訊息尖峰。使用佈建模式設定的 Amazon SQS 事件來源映射擴展速度快 3 倍 （每分鐘最多 1，000 個並行調用），並支援比預設 Amazon SQS 事件來源映射功能高 16 倍的並行調用 （最多 20，000 個並行調用）。我們建議您針對具有嚴格效能需求的 Amazon SQS 事件驅動型工作負載使用佈建模式，例如處理市場資料饋送的金融服務公司、提供即時個人化建議的電子商務平台，以及管理即時玩家互動的遊戲公司。使用佈建模式會產生額外費用。如需詳細的定價，請參閱 [AWS Lambda 定價](https://aws.amazon.com/lambda/pricing/)。

佈建模式中的每個事件輪詢器最多可處理每秒 1 MB 的輸送量、最多 10 個並行調用，或每秒最多 10 個 Amazon SQS 輪詢 API 呼叫。事件輪詢器 (MinimumPollers) 數目下限的接受值範圍介於 2 到 200 之間，預設值為 2。事件輪詢器 (MaximumPollers) 數目上限的接受值範圍介於 2 到 2，000 之間，預設值為 200。MaximumPollers 必須大於或等於 MinimumPollers。

### 判斷所需的事件輪詢器
<a name="sqs-determining-event-pollers"></a>

若要預估在 SQS ESM 使用佈建模式時確保最佳訊息處理效能所需的事件輪詢器數量，請為您的應用程式收集下列指標：需要低延遲處理的每秒尖峰 SQS 事件數、平均 SQS 事件承載大小、平均 Lambda 函數持續時間，以及設定的批次大小。

首先，您可以使用下列公式，為您的工作負載預估事件輪詢器支援的每秒 SQS 事件數 (EPS)：

```
EPS per event poller = 
        minimum(
            ceiling(1024 / average event size in KB),
            ceiling(10 / average function duration in seconds) * batch size, 
            min(100, 10 * batch size)
                )
```

然後，您可以使用以下公式計算所需的最低輪詢器數量。此計算可確保您佈建足夠的容量來處理尖峰流量需求。

```
Required event pollers = (Peak number of events per second in Queue) / EPS per event poller
```

假設工作負載的預設批次大小為 10、平均事件大小為 3 KB、平均函數持續時間為 100 毫秒，且需要每秒處理 1，000 個事件。在此案例中，每個事件輪詢器每秒將支援約 100 個事件 (EPS)。因此，您應該將最低輪詢器設定為 10，以充分處理您的尖峰流量需求。如果您的工作負載具有相同的特性，但平均函數持續時間為 1 秒，則每個輪詢器將僅支援 10 個 EPS，要求您設定 100 個最低輪詢器，以低延遲支援每秒 1，000 個事件。

建議使用預設批次大小 10 或更高，以最大限度地提高佈建模式事件輪詢器的效率。較高的批次大小可讓每個輪詢器在每次調用時處理更多事件，以提高輸送量和成本效益。規劃事件輪詢器容量時，請考量潛在的流量峰值，並考慮將 minimumPollers 值稍高於計算的最小值，以提供緩衝區。此外，隨著時間的推移監控工作負載特性，因為訊息大小、函數持續時間或流量模式的變更可能需要調整事件輪詢器組態，以維持最佳效能和成本效益。為了精確規劃容量，我們建議您測試特定工作負載，以判斷每個事件輪詢器可以驅動的實際 EPS。

## 設定 Amazon SQS 事件來源映射的佈建模式
<a name="sqs-configuring-provisioned-mode"></a>

您可以使用主控台或 Lambda API，為 Amazon SQS 事件來源映射設定佈建模式。

**設定現有 Amazon SQS 事件來源映射的佈建模式 （主控台）**

1. 開啟 Lambda 主控台中的[函數頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇具有您要為其設定佈建模式之 Amazon SQS 事件來源映射的函數。

1. 選擇**組態**，然後選擇**觸發條件**。

1. 選擇您要為其設定佈建模式的 Amazon SQS 事件來源映射，然後選擇**編輯**。

1. 在**事件來源映射組態**下，選擇**設定佈建模式**。
   + 針對**最低事件輪詢器**，輸入介於 2 到 200 之間的值。如果您未指定值，Lambda 會選擇預設值 2。
   + 針對**事件輪詢器上限**，輸入介於 2 到 2，000 之間的值。此值必須大於或等於**事件輪詢器下限**值。如果您沒有指定值，則 Lambda 會選擇預設值 200。

1. 選擇**儲存**。

您可以使用 中的 `ProvisionedPollerConfig` 物件，以程式設計方式設定佈建模式`EventSourceMappingConfiguration`。例如，下列 `UpdateEventSourceMapping` CLI 命令會設定 5 `MinimumPollers`的值，以及 100 `MaximumPollers`的值。

```
aws lambda update-event-source-mapping \
    --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 \
    --provisioned-poller-config '{"MinimumPollers": 5, "MaximumPollers": 100}'
```

設定佈建模式後，可以透過監控 `ProvisionedPollers` 指標來觀察工作負載的事件輪詢器使用情況。如需詳細資訊，請參閱事件來源映射指標。

若要停用佈建模式並返回預設 （隨需） 模式，您可以使用下列 `UpdateEventSourceMapping` CLI 命令：

```
aws lambda update-event-source-mapping \
    --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 \
    --provisioned-poller-config '{}'
```

**注意**  
佈建模式無法與最大並行設定搭配使用。使用佈建模式時，您可以透過事件輪詢器的數量上限來控制並行上限。

如需設定佈建模式的詳細資訊，請參閱 [建立和設定 Amazon SQS 事件來源映射](services-sqs-configure.md)。

## 標準佇列訊息事件範例
<a name="example-standard-queue-message-event"></a>

**Example Amazon SQS 訊息事件 (標準佇列)**  

```
{
    "Records": [
        {
            "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d",
            "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...",
            "body": "Test message.",
            "attributes": {
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1545082649183",
                "SenderId": "AIDAIENQZJOLO23YVJ4VO",
                "ApproximateFirstReceiveTimestamp": "1545082649185"
            },
            "messageAttributes": {
                "myAttribute": {
                    "stringValue": "myValue", 
                    "stringListValues": [], 
                    "binaryListValues": [], 
                    "dataType": "String"
                }
            },
            "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
            "eventSource": "aws:sqs",
            "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue",
            "awsRegion": "us-east-2"
        },
        {
            "messageId": "2e1424d4-f796-459a-8184-9c92662be6da",
            "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
            "body": "Test message.",
            "attributes": {
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1545082650636",
                "SenderId": "AIDAIENQZJOLO23YVJ4VO",
                "ApproximateFirstReceiveTimestamp": "1545082650649"
            },
            "messageAttributes": {},
            "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
            "eventSource": "aws:sqs",
            "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue",
            "awsRegion": "us-east-2"
        }
    ]
}
```

依預設，Lambda 會一次輪詢佇列中最多 10 則訊息，並將該批次傳送給函數。為避免調用具有少量記錄的函數，您可設定批次間隔，讓事件來源緩衝記錄最長達五分鐘。調用函數之前，Lambda 會繼續從標準佇列輪詢訊息，直至批次間隔到期、達到[調用承載大小配額](gettingstarted-limits.md)，或達到設定的批次大小上限為止。

如果您使用的是批次時間範圍，並且您的 SQS 佇列包含非常低的流量，Lambda 可能會等到 20 秒，然後再調用您的函數。即使您將批次時間範圍設定為低於 20 秒也是如此。

**注意**  
在 Java 中，還原序列化 JSON 時可能會遇到 null 指標錯誤。這可能是由於 JSON 物件映射器對「Records」和「eventSourceARN」案例轉換的方式所致。

## FIFO 佇列訊息事件範例
<a name="sample-fifo-queues-message-event"></a>

對於 FIFO 佇列，記錄包含與重複資料刪除和定序相關的其他屬性。

**Example Amazon SQS 訊息事件 (FIFO 佇列)**  

```
{
    "Records": [
        {
            "messageId": "11d6ee51-4cc7-4302-9e22-7cd8afdaadf5",
            "receiptHandle": "AQEBBX8nesZEXmkhsmZeyIE8iQAMig7qw...",
            "body": "Test message.",
            "attributes": {
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1573251510774",
                "SequenceNumber": "18849496460467696128",
                "MessageGroupId": "1",
                "SenderId": "AIDAIO23YVJENQZJOL4VO",
                "MessageDeduplicationId": "1",
                "ApproximateFirstReceiveTimestamp": "1573251510774"
            },
            "messageAttributes": {},
            "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
            "eventSource": "aws:sqs",
            "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:fifo.fifo",
            "awsRegion": "us-east-2"
        }
    ]
}
```