

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# Amazon SNS 消息批处理
<a name="sns-batch-api-actions"></a>

## 什么是消息批处理？
<a name="what-is-message-batching"></a>

在各个 `Publish` API 请求中向标准或 FIFO 主题发布消息的替代方法，该方法使用 Amazon SNS `PublishBatch` API 在单个 API 请求中最多发布 10 条消息。批量发送消息可以帮助您利用 Amazon SNS 将与连接分布式应用程序（[A2A 消息收发](sns-system-to-system-messaging.md)）或者向人们发送通知（[A2P 消息收发](sns-user-notifications.md)）相关的成本最高降低 10 倍。根据您运营所在区域，Amazon SNS 对每秒可以向某个主题发布的消息数量设定了配额。有关 API 限额的更多信息，请参阅《AWS 一般参考》**中的 [Amazon SNS 端点和限额](https://docs.aws.amazon.com/general/latest/gr/sns.html)页面。

**注意**  
您在单个 `PublishBatch` API 请求中发送的所有消息的总合计大小不能超过 262144 字节（256 KiB）。  
`PublishBatch` API 将相同的 `Publish` API 操作用于 IAM 策略。

## 消息批处理是如何工作的？
<a name="message-batching-how-it-works"></a>

使用 `PublishBatch` API 发布消息与使用 `Publish` API 发布消息类似。主要的区别在于，需要给 `PublishBatch` API 请求中的每条消息分配一个唯一的批处理 ID（最多 80 个字符）。这样，Amazon SNS 可以为批处理中的每条消息返回单独的 API 响应，以确认每条消息均已发布或发生故障。对于发布到 FIFO 主题的消息，除了包括分配唯一的批处理 ID 之外，还需要为每条单独的消息包括 `MessageDeduplicationID` 和 `MessageGroupId`。

## 示例
<a name="message-batching-examples"></a>

**向标准主题发布一批 10 条的消息**

```
// Imports
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.PublishBatchRequest;
import software.amazon.awssdk.services.sns.model.PublishBatchRequestEntry;
import software.amazon.awssdk.services.sns.model.PublishBatchResponse;
import software.amazon.awssdk.services.sns.model.SnsException;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

// Code
private static final int MAX_BATCH_SIZE = 10;

public static void publishBatchToTopic(SnsClient snsClient, String topicArn, int batchSize) {
    try {
        // Validate the batch size
        if (batchSize > MAX_BATCH_SIZE) {
            throw new IllegalArgumentException("Batch size cannot exceed " + MAX_BATCH_SIZE);
        }

        // Create the batch entries
        List<PublishBatchRequestEntry> entries = IntStream.range(0, batchSize)
                .mapToObj(i -> PublishBatchRequestEntry.builder()
                        .id("id" + i)
                        .message("message" + i)
                        .build())
                .collect(Collectors.toList());

        // Build the batch request
        PublishBatchRequest request = PublishBatchRequest.builder()
                .topicArn(topicArn)
                .publishBatchRequestEntries(entries)
                .build();

        // Publish the batch request
        PublishBatchResponse response = snsClient.publishBatch(request);

        // Handle successful messages
        response.successful().forEach(success -> {
            System.out.println("Successful Batch Id: " + success.id());
            System.out.println("Message Id: " + success.messageId());
        });

        // Handle failed messages
        response.failed().forEach(failure -> {
            System.err.println("Failed Batch Id: " + failure.id());
            System.err.println("Error Code: " + failure.code());
            System.err.println("Sender Fault: " + failure.senderFault());
            System.err.println("Error Message: " + failure.message());
        });

    } catch (SnsException e) {
        // Log and handle exceptions
        System.err.println("SNS Exception: " + e.awsErrorDetails().errorMessage());
    } catch (IllegalArgumentException e) {
        System.err.println("Validation Error: " + e.getMessage());
    }
}
```

**向 FIFO 主题发布一批 10 条的消息**

```
// Imports
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.PublishBatchRequest;
import software.amazon.awssdk.services.sns.model.PublishBatchRequestEntry;
import software.amazon.awssdk.services.sns.model.PublishBatchResponse;
import software.amazon.awssdk.services.sns.model.BatchResultErrorEntry;
import software.amazon.awssdk.services.sns.model.SnsException;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

// Code
private static final int MAX_BATCH_SIZE = 10;

public static void publishBatchToFifoTopic(SnsClient snsClient, String topicArn) {
    try {
        // Create the batch entries to send
        List<PublishBatchRequestEntry> entries = IntStream.range(0, MAX_BATCH_SIZE)
                .mapToObj(i -> PublishBatchRequestEntry.builder()
                        .id("id" + i)
                        .message("message" + i)
                        .messageGroupId("groupId")
                        .messageDeduplicationId("deduplicationId" + i)
                        .build())
                .collect(Collectors.toList());

        // Create the batch request
        PublishBatchRequest request = PublishBatchRequest.builder()
                .topicArn(topicArn)
                .publishBatchRequestEntries(entries)
                .build();

        // Publish the batch request
        PublishBatchResponse response = snsClient.publishBatch(request);

        // Handle the successfully sent messages
        response.successful().forEach(success -> {
            System.out.println("Batch Id for successful message: " + success.id());
            System.out.println("Message Id for successful message: " + success.messageId());
            System.out.println("Sequence Number for successful message: " + success.sequenceNumber());
        });

        // Handle the failed messages
        response.failed().forEach(failure -> {
            System.err.println("Batch Id for failed message: " + failure.id());
            System.err.println("Error Code for failed message: " + failure.code());
            System.err.println("Sender Fault for failed message: " + failure.senderFault());
            System.err.println("Failure Message for failed message: " + failure.message());
        });

    } catch (SnsException e) {
        // Handle any exceptions from the request
        System.err.println("SNS Exception: " + e.awsErrorDetails().errorMessage());
    }
}
```