

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Amazon-SQS-Stapelaktionen
<a name="sqs-batch-api-actions"></a>

Amazon SQS bietet Batch-Aktionen, mit denen Sie Kosten senken und bis zu 10 Nachrichten mit einer einzigen Aktion bearbeiten können. Zu diesen Batch-Aktionen gehören:
+ `[SendMessageBatch](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessageBatch.html)`
+ `[DeleteMessageBatch](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_DeleteMessageBatch.html)`
+ `[ChangeMessageVisibilityBatch](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ChangeMessageVisibilityBatch.html)`

Mithilfe von Batch-Aktionen können Sie mehrere Operationen in einem einzigen API-Aufruf ausführen, wodurch die Leistung optimiert und die Kosten gesenkt werden können. Sie können die Batch-Funktionalität mithilfe der Abfrage-API oder eines beliebigen AWS SDK nutzen, das Amazon SQS SQS-Batch-Aktionen unterstützt.

**Wichtige Details**
+ **Größenbeschränkung für Nachrichten:** Die Gesamtgröße aller Nachrichten, die in einem einzigen `SendMessageBatch` Anruf gesendet werden, darf 1.048.576 Byte (1 MiB) nicht überschreiten
+ **Berechtigungen:** Sie können Berechtigungen für, oder nicht explizit festlegen. `SendMessageBatch` `DeleteMessageBatch` `ChangeMessageVisibilityBatch` Stattdessen werden durch das Festlegen von Berechtigungen für `SendMessage``DeleteMessage`, oder Berechtigungen für die entsprechenden Batchversionen der Aktionen `ChangeMessageVisibility` festgelegt.
+ **Konsolenunterstützung:** Die Amazon SQS SQS-Konsole unterstützt keine Batch-Aktionen. Sie müssen die Abfrage-API oder ein AWS SDK verwenden, um Batch-Operationen durchzuführen.

## Stapelverarbeitungsaktionen für Nachrichten
<a name="batching-message-actions"></a>

Um Kosten und Effizienz weiter zu optimieren, sollten Sie die folgenden bewährten Methoden für die Batchverarbeitung von Nachrichtenaktionen berücksichtigen:
+ **Batch-API-Aktionen:** Verwenden Sie die [Amazon SQS SQS-Batch-API-Aktionen](#sqs-batch-api-actions), um Nachrichten zu senden, zu empfangen und zu löschen und um das Timeout für die Nachrichtensichtbarkeit mehrerer Nachrichten mit einer einzigen Aktion zu ändern. Dies reduziert die Anzahl der API-Aufrufe und die damit verbundenen Kosten.
+ **Clientseitige Pufferung und lange Abfragen: Kombinieren Sie die clientseitige Pufferung** [mit der Batchverarbeitung von Anfragen, indem Sie lange Abfragen zusammen mit dem gepufferten asynchronen Client verwenden, der im Lieferumfang von enthalten ist.](sqs-client-side-buffering-request-batching.md) AWS SDK für Java Dieser Ansatz trägt dazu bei, die Anzahl der Anfragen zu minimieren und die Verarbeitung großer Nachrichtenmengen zu optimieren.

**Anmerkung**  
Der Amazon SQS Buffered Asynchronous Client unterstützt derzeit keine FIFO-Warteschlangen.

# Aktivierung der clientseitigen Pufferung und der Batchverarbeitung von Anfragen mit Amazon SQS
<a name="sqs-client-side-buffering-request-batching"></a>

[AWS SDK für Java](https://aws.amazon.com/sdkforjava/) enthält den `AmazonSQSBufferedAsyncClient`, der auf Amazon SQS zugreift. Dieser Client ermöglicht eine einfache Batchverarbeitung von Anfragen mithilfe der clientseitigen Pufferung. Aufrufe vom Client werden zuerst gepuffert und dann als Batch-Anfrage an Amazon SQS gesendet.

Mit der clientseitigen Pufferung können bis zu 10 Anforderungen zwischengespeichert und als Stapelanforderung gesendet werden. Dadurch werden Ihre Kosten für die Verwendung von Amazon SQS gesenkt und die Anzahl der gesendeten Anforderungen verringert. `AmazonSQSBufferedAsyncClient` puffert synchrone und asynchrone Aufrufe. Als Stapel verarbeitete Anforderungen und die Unterstützung für [langes Abrufen](sqs-short-and-long-polling.md) können ebenfalls zu einem erhöhten Durchsatz beitragen. Weitere Informationen finden Sie unter [Steigerung des Durchsatzes durch horizontale Skalierung und Action-Batching mit Amazon SQS](sqs-throughput-horizontal-scaling-and-batching.md).

Da `AmazonSQSBufferedAsyncClient` die gleiche Schnittstelle implementiert wie `AmazonSQSAsyncClient`, sollte die Migration von `AmazonSQSAsyncClient` zu `AmazonSQSBufferedAsyncClient` in der Regel lediglich minimale Änderungen an Ihrem vorhandenen Code erfordern.

**Anmerkung**  
Der Amazon SQS Buffered Asynchronous Client unterstützt derzeit keine FIFO-Warteschlangen.

## Amazon verwenden SQSBuffered AsyncClient
<a name="using-buffered-async-client"></a>

Bevor Sie beginnen, führen Sie die Schritte in [Einrichten von Amazon SQS](sqs-setting-up.md) aus. 

### AWS SDK for Java 1.x
<a name="using-buffered-async-client-java1"></a>

Für AWS SDK for Java 1.x können Sie ein neues erstellen, das auf dem folgenden Beispiel `AmazonSQSBufferedAsyncClient` basiert:

```
// Create the basic Amazon SQS async client
final AmazonSQSAsync sqsAsync = new AmazonSQSAsyncClient();
 
// Create the buffered client
final AmazonSQSAsync bufferedSqs = new AmazonSQSBufferedAsyncClient(sqsAsync);
```

Nachdem Sie den neuen `AmazonSQSBufferedAsyncClient` erstellt haben, können Sie ihn verwenden, um mehrere Anforderungen an Amazon SQS zu senden (wie mit dem `AmazonSQSAsyncClient`), beispielsweise:

```
final CreateQueueRequest createRequest = new CreateQueueRequest().withQueueName("MyQueue");
 
final CreateQueueResult res = bufferedSqs.createQueue(createRequest);
 
final SendMessageRequest request = new SendMessageRequest();
final String body = "Your message text" + System.currentTimeMillis();
request.setMessageBody( body );
request.setQueueUrl(res.getQueueUrl());
 
final Future<SendMessageResult> sendResult = bufferedSqs.sendMessageAsync(request);
 
final ReceiveMessageRequest receiveRq = new ReceiveMessageRequest()
    .withMaxNumberOfMessages(1)
    .withQueueUrl(queueUrl);
final ReceiveMessageResult rx = bufferedSqs.receiveMessage(receiveRq);
```

### Amazon konfigurieren SQSBuffered AsyncClient
<a name="configuring-buffered-async-client"></a>

`AmazonSQSBufferedAsyncClient` ist mit Einstellungen vorkonfiguriert, die für die meisten Anwendungsfälle verwendet werden können. Sie können `AmazonSQSBufferedAsyncClient` weiter konfigurieren, z. B.:

1. Erstellen Sie eine Instance der Klasse `QueueBufferConfig` mit den erforderlichen Konfigurationsparametern.

1. Stellen Sie die Instance dem `AmazonSQSBufferedAsyncClient`-Konstruktor zur Verfügung.

```
// Create the basic Amazon SQS async client
final AmazonSQSAsync sqsAsync = new AmazonSQSAsyncClient();
 
final QueueBufferConfig config = new QueueBufferConfig()
    .withMaxInflightReceiveBatches(5)
    .withMaxDoneReceiveBatches(15);
 
// Create the buffered client
final AmazonSQSAsync bufferedSqs = new AmazonSQSBufferedAsyncClient(sqsAsync, config);
```


**QueueBufferConfig Konfigurationsparameter**  

| Parameter | Standardwert | Description | 
| --- | --- | --- | 
| longPoll | true |  Wenn `longPoll` auf `true` festgelegt ist, versucht `AmazonSQSBufferedAsyncClient`, Nachrichten durch langes Abrufen abzurufen.  | 
| longPollWaitTimeoutSeconds | 20 s |  Die maximale Dauer (in Sekunden), die ein `ReceiveMessage`-Aufruf beim Warten auf das Auftauchen von Nachrichten in der Warteschlange auf dem Server blockiert wird, bevor er mit einem leeren Empfangsergebnis zurückkehrt.  Wenn langes Abrufen deaktiviert ist, hat diese Einstellung hat keine Auswirkungen.   | 
| maxBatchOpenMs | 200 ms |  Die maximale Dauer (in Millisekunden), die ein ausgehender Aufruf auf andere Aufrufe desselben Typs wartet, mit denen er Nachrichten desselben Typs zu einem Stapel zusammenfasst. Je höher die Einstellung, desto weniger Stapel sind erforderlich, um dieselbe Anzahl an Aufgaben auszuführen (der erste Aufruf eines Stapels muss jedoch länger in der Warteschlange warten). Wenn Sie diesen Parameter auf `0` einstellen, warten gesendete Anforderungen nicht auf andere Anforderungen, wodurch die Stapelverarbeitung effektiv deaktiviert wird.  | 
| maxBatchSize | 10 Anforderungen pro Stapel |  Die maximale Anzahl von Nachrichten, die in einer einzelnen Stapelanforderung zusammengefasst werden. Je höher die Einstellung, desto weniger Stapel müssen die gleiche Anzahl von Anforderungen ausführen.  10 Anforderungen pro Stapel ist der maximal zulässige Wert für Amazon SQS.   | 
| maxBatchSizeBytes | 1 MiB |  Die maximale Größe eines Nachrichtenstapels in Bytes, die der Client versucht, an Amazon SQS zu senden.  1 MiB ist der maximal zulässige Wert für Amazon SQS.   | 
| maxDoneReceiveBatches | 10 Stapel |  Die maximale Anzahl von Empfangsstapeln, die `AmazonSQSBufferedAsyncClient` vorab abruft und clientseitig speichert. Je höher die Einstellung, desto mehr Empfangsanforderungen können erfüllt werden, ohne dass ein Aufruf an Amazon SQS gestartet werden muss (je mehr Nachrichten jedoch vorab abgerufen werden, desto länger bleiben sie im Puffer, was bedeutet, dass deren Zeitbeschränkung für die Sichtbarkeit abläuft).  `0`gibt an, dass der gesamte Vorabruf von Nachrichten deaktiviert ist und Nachrichten nur bei Bedarf abgerufen werden.   | 
| maxInflightOutboundBatches | 5 Stapel |  Die maximale Anzahl der aktiven ausgehenden Stapel, die gleichzeitig verarbeitet werden können. Je höher die Einstellung, desto schneller können ausgehende Stapel gesendet werden (in Abhängigkeit von anderen Kontingenten, z. B. durch CPU oder Bandbreite) und desto mehr Threads werden von `AmazonSQSBufferedAsyncClient` verbraucht.  | 
| maxInflightReceiveBatches | 10 Stapel |  Die maximale Anzahl der aktiven Empfangsstapel, die gleichzeitig verarbeitet werden können. Je höher die Einstellung, desto mehr Nachrichten können empfangen werden (in Abhängigkeit von anderen Kontingenten, z. B. durch CPU oder Bandbreite) und desto mehr Threads werden von `AmazonSQSBufferedAsyncClient` verbraucht.  `0`gibt an, dass der gesamte Vorabruf von Nachrichten deaktiviert ist und Nachrichten nur bei Bedarf abgerufen werden.   | 
| visibilityTimeoutSeconds | -1 |  Wenn dieser Parameter auf einen positiven Wert ungleich null festgelegt ist, überschreibt die hier festgelegte Zeitbeschränkung für die Sichtbarkeit diejenige, die für die Warteschlange festgelegt ist, über die Nachrichten abgerufen werden.  `-1` gibt an, dass die Standardeinstellung für die Warteschlange ausgewählt ist. Sie können als Zeitbeschränkung für die Sichtbarkeit nicht `0` festlegen.   | 

### AWS SDK for Java 2.x
<a name="using-buffered-async-client-java2"></a>

Für AWS SDK for Java 2.x können Sie ein neues erstellen, das auf dem folgenden Beispiel `SqsAsyncBatchManager` basiert:

```
// Create the basic Sqs Async Client
SqsAsyncClient sqs = SqsAsyncClient.builder() 
    .region(Region.US_EAST_1) 
    .build();

// Create the batch manager
SqsAsyncBatchManager sqsAsyncBatchManager = sqs.batchManager();
```

Nachdem Sie den neuen `SqsAsyncBatchManager` erstellt haben, können Sie ihn verwenden, um mehrere Anforderungen an Amazon SQS zu senden (wie mit dem `SqsAsyncClient`), beispielsweise:

```
final String queueName = "MyAsyncBufferedQueue" + UUID.randomUUID();
final CreateQueueRequest request = CreateQueueRequest.builder().queueName(queueName).build();
final String queueUrl = sqs.createQueue(request).join().queueUrl();
System.out.println("Queue created: " + queueUrl);


// Send messages
CompletableFuture<SendMessageResponse> sendMessageFuture;
for (int i = 0; i < 10; i++) {
    final int index = i;
    sendMessageFuture = sqsAsyncBatchManager.sendMessage(
            r -> r.messageBody("Message " + index).queueUrl(queueUrl));
    SendMessageResponse response= sendMessageFuture.join();
    System.out.println("Message " + response.messageId() + " sent!");
}

// Receive messages with customized configurations
CompletableFuture<ReceiveMessageResponse> receiveResponseFuture = customizedBatchManager.receiveMessage(
        r -> r.queueUrl(queueUrl)
                .waitTimeSeconds(10)
                .visibilityTimeout(20)
                .maxNumberOfMessages(10)
);
System.out.println("You have received " + receiveResponseFuture.join().messages().size() + " messages in total.");

// Delete messages
DeleteQueueRequest deleteQueueRequest =  DeleteQueueRequest.builder().queueUrl(queueUrl).build();
int code = sqs.deleteQueue(deleteQueueRequest).join().sdkHttpResponse().statusCode();
System.out.println("Queue is deleted, with statusCode " + code);
```

### Konfiguration SqsAsyncBatchManager
<a name="configuring-SqsAsyncBatchManager"></a>

`SqsAsyncBatchManager` ist mit Einstellungen vorkonfiguriert, die für die meisten Anwendungsfälle verwendet werden können. Sie können `SqsAsyncBatchManager` weiter konfigurieren, z. B.:

Erstellen einer benutzerdefinierten Konfiguration über`SqsAsyncBatchManager.Builder`:

```
SqsAsyncBatchManager customizedBatchManager = SqsAsyncBatchManager.builder() 
    .client(sqs)
    .scheduledExecutor(Executors.newScheduledThreadPool(5))
    .overrideConfiguration(b -> b 
        .maxBatchSize(10)
        .sendRequestFrequency(Duration.ofMillis(200))
        .receiveMessageMinWaitDuration(Duration.ofSeconds(10))
        .receiveMessageVisibilityTimeout(Duration.ofSeconds(20)) 
        .receiveMessageAttributeNames(Collections.singletonList("*"))
        .receiveMessageSystemAttributeNames(Collections.singletonList(MessageSystemAttributeName.ALL)))
    .build();
```


**`BatchOverrideConfiguration`-Parameter**  

| Parameter | Standardwert | Description | 
| --- | --- | --- | 
| maxBatchSize |  10 Anforderungen pro Stapel  | Die maximale Anzahl von Nachrichten, die in einer einzelnen Stapelanforderung zusammengefasst werden. Je höher die Einstellung, desto weniger Stapel müssen die gleiche Anzahl von Anforderungen ausführen.  Der zulässige Höchstwert für Amazon SQS beträgt 10 Anfragen pro Stapel.  | 
| sendRequestFrequency |  200 ms  | Die maximale Dauer (in Millisekunden), die ein ausgehender Aufruf auf andere Aufrufe desselben Typs wartet, mit denen er Nachrichten desselben Typs zu einem Stapel zusammenfasst. Je höher die Einstellung, desto weniger Stapel sind erforderlich, um dieselbe Anzahl an Aufgaben auszuführen (der erste Aufruf eines Stapels muss jedoch länger in der Warteschlange warten). Wenn Sie diesen Parameter auf `0` einstellen, warten gesendete Anforderungen nicht auf andere Anforderungen, wodurch die Stapelverarbeitung effektiv deaktiviert wird. | 
| receiveMessageVisibilityTimeout |  -1  | Wenn dieser Parameter auf einen positiven Wert ungleich null festgelegt ist, überschreibt die hier festgelegte Zeitbeschränkung für die Sichtbarkeit diejenige, die für die Warteschlange festgelegt ist, über die Nachrichten abgerufen werden.   `1` gibt an, dass die Standardeinstellung für die Warteschlange ausgewählt ist. Sie können als Zeitbeschränkung für die Sichtbarkeit nicht `0` festlegen.   | 
| receiveMessageMinWaitDuration |  50 ms  | Die Mindestzeit (in Millisekunden), die ein `receiveMessage` Anruf darauf wartet, dass verfügbare Nachrichten abgerufen werden. Je höher die Einstellung, desto weniger Batches sind erforderlich, um dieselbe Anzahl von Anfragen auszuführen.  | 

# Steigerung des Durchsatzes durch horizontale Skalierung und Action-Batching mit Amazon SQS
<a name="sqs-throughput-horizontal-scaling-and-batching"></a>

Amazon SQS unterstützt Nachrichtenübermittlung mit hohem Durchsatz. Einzelheiten zu Durchsatzgrenzen finden Sie unter. [Amazon SQS SQS-Nachrichtenkontingente](quotas-messages.md)

So maximieren Sie den Durchsatz:
+ [Skalieren](#horizontal-scaling) Sie Hersteller und Verbraucher horizontal, indem Sie jeweils weitere Instanzen hinzufügen.
+ Verwenden Sie [Action-Batching](#request-batching), um mehrere Nachrichten in einer einzigen Anfrage zu senden oder zu empfangen und so den Aufwand für API-Aufrufe zu reduzieren.

## Horizontale Skalierung
<a name="horizontal-scaling"></a>

Da Sie über ein HTTP-Anfrage-Antwort-Protokoll auf Amazon SQS zugreifen, beschränkt die *Anforderungslatenz* (der Zeitraum zwischen dem Initiieren einer Anforderung und dem Empfangen einer Antwort) den Durchsatz, den Sie über einen einzelnen Thread über eine einzelne Verbindung erzielen können. Wenn beispielsweise der Mittelwert der Latenz eines auf EC2 basierenden Clients zu Amazon SQS in derselben Region ca. 20 ms beträgt, liegt der Mittelwert des maximalen Durchsatzes eines einzelnen Threads über eine einzelne Verbindung bei 50 TPS. 

*Horizontale Skalierung* bedeutet, dass die Anzahl Ihrer Nachrichtenproduzenten (die `[SendMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html)`-Anforderungen erstellen) und Konsumenten (die `[ReceiveMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html)`- und `[DeleteMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_DeleteMessage.html)`-Anforderungen erstellen) erhöht wird, um den Gesamtdurchsatz der Warteschlange zu steigern. Sie können auf drei Arten horizontal skalieren:
+ Erhöhen der Anzahl der Threads pro Client
+ Hinzufügen weiterer Clients
+ Erhöhen der Anzahl der Threads pro Client und Hinzufügen weiterer Clients

Wenn Sie weitere Clients hinzufügen, erzielen Sie eine wesentliche lineare Steigerung des Durchsatzes der Warteschlange. Wenn Sie die Anzahl der Clients beispielsweise verdoppeln, verdoppeln Sie auch den Durchsatz. 

## Stapelverarbeitung von Aktionen
<a name="request-batching"></a>

Mit der *Stapelverarbeitung* wird in den einzelnen Roundtrips an den Service mehr Arbeit ausgeführt (z. B. das Senden mehrerer Nachrichten mit einer einzelnen `SendMessageBatch`-Anforderung). Die Amazon-SQS-Stapelaktionen sind `[SendMessageBatch](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessageBatch.html)`, `[DeleteMessageBatch](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_DeleteMessageBatch.html)` und `[ChangeMessageVisibilityBatch](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ChangeMessageVisibilityBatch.html)`. Um die Stapelverarbeitung zu nutzen, ohne Ihre Produzenten und Konsumenten zu ändern, können Sie den [Amazon SQS Buffered Asynchronous Client](sqs-client-side-buffering-request-batching.md) verwenden.

**Anmerkung**  
Da mit `[ReceiveMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html)` 10 Nachrichten gleichzeitig verarbeitet werden können, wird keine `ReceiveMessageBatch`-Aktion ausgeführt.

Die Stapelverarbeitung verteilt die Latenz der Stapelaktion über mehrere Nachrichten in einer Stapelanforderung, anstatt die gesamte Latenz für eine einzelne Nachricht (z. B. eine `[SendMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html)`-Anforderung) zu akzeptieren. Da jeder Roundtrip mehr Arbeit verrichtet, nutzen Stapelanforderungen Threads und Verbindungen effektiver und verbessern somit den Durchsatz.

Sie können die Stapelverarbeitung mit der horizontalen Skalierung kombinieren, um einen Durchsatz mit weniger Threads, Verbindungen und Anforderungen zu bieten, als dies bei einzelnen Nachrichtenanforderungen der Fall ist. Mit Amazon-SQS-Aktionen im Stapel können Sie bis zu 10 Nachrichten gleichzeitig senden, empfangen oder löschen. Da in Amazon SQS Gebühren nach Anforderung berechnet werden, kann die Stapelverarbeitung wesentlich zur Verringerung der Kosten beitragen. 

Mit der Stapelverarbeitung kann eine gewisse Komplexität für Ihre Anwendung einhergehen (z. B. muss die Anwendung Nachrichten vor der Übermittlung sammeln oder gelegentlich länger auf eine Antwort warten). Die Stapelverarbeitung kann in folgenden Fällen jedoch weiterhin effektiv sein: 
+ Ihre Anwendung erstellt in kurzer Zeit viele Nachrichten, sodass es niemals zu einer sehr langen Verzögerung kommt. 
+ Anders als typische Nachrichtenproduzenten, die Nachrichten als Antwort auf Ereignisse senden müssen, die sie nicht steuern können, ruft ein Nachrichtenkonsument Nachrichten nach eigenem Ermessen aus einer Warteschlange ab. 

**Wichtig**  
Eine Stapelanforderung kann erfolgreich ausgeführt werden, auch wenn einzelne Nachrichten im Stapel fehlgeschlagen sind. Überprüfen Sie nach einer Stapelanforderung stets, ob einzelne Nachrichten nicht zugestellt werden konnten, und führen Sie diese bei Bedarf erneut aus.

## Funktionierendes Java-Beispiel für einzelne Operationsanforderungen und Stapelanforderungen
<a name="working-java-example-batch-requests"></a>

### Voraussetzungen
<a name="batch-request-java-example-prerequisites"></a>

Fügen Sie dem Pfad für Ihre Java-Build-Klasse die Pakete `aws-java-sdk-sqs.jar`, `aws-java-sdk-ec2.jar` und `commons-logging.jar` hinzu. Das folgende Beispiel zeigt diese Abhängigkeiten in der `pom.xml`-Datei eines Maven-Projekts.

```
<dependencies>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-sqs</artifactId>
        <version>LATEST</version>
    </dependency>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-ec2</artifactId>
        <version>LATEST</version>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>LATEST</version>
    </dependency>
</dependencies>
```

### SimpleProducerConsumer.java
<a name="batch-request-java-example-code"></a>

Das nachstehende Java-Code-Beispiel veranschaulicht ein einfaches Produzent-Konsument-Muster. Der Haupt-Thread ruft eine Reihe von Produzenten- und Konsumenten-Threads auf, die 1-KB-Nachrichten für eine bestimmte Zeit verarbeiten. Dieses Beispiel enthält Produzenten und Konsumenten, die einzelne Operationsanforderungen senden, und solche, die Stapelanforderungen senden.

```
/*
 * Copyright 2010-2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  https://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 */

import com.amazonaws.AmazonClientException;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Start a specified number of producer and consumer threads, and produce-consume
 * for the least of the specified duration and 1 hour. Some messages can be left
 * in the queue because producers and consumers might not be in exact balance.
 */
public class SimpleProducerConsumer {

    // The maximum runtime of the program.
    private final static int MAX_RUNTIME_MINUTES = 60;
    private final static Log log = LogFactory.getLog(SimpleProducerConsumer.class);

    public static void main(String[] args) throws InterruptedException {

        final Scanner input = new Scanner(System.in);

        System.out.print("Enter the queue name: ");
        final String queueName = input.nextLine();

        System.out.print("Enter the number of producers: ");
        final int producerCount = input.nextInt();

        System.out.print("Enter the number of consumers: ");
        final int consumerCount = input.nextInt();

        System.out.print("Enter the number of messages per batch: ");
        final int batchSize = input.nextInt();

        System.out.print("Enter the message size in bytes: ");
        final int messageSizeByte = input.nextInt();

        System.out.print("Enter the run time in minutes: ");
        final int runTimeMinutes = input.nextInt();

        /*
         * Create a new instance of the builder with all defaults (credentials
         * and region) set automatically. For more information, see Creating
         * Service Clients in the AWS SDK for Java Developer Guide.
         */
        final ClientConfiguration clientConfiguration = new ClientConfiguration()
                .withMaxConnections(producerCount + consumerCount);

        final AmazonSQS sqsClient = AmazonSQSClientBuilder.standard()
                .withClientConfiguration(clientConfiguration)
                .build();

        final String queueUrl = sqsClient
                .getQueueUrl(new GetQueueUrlRequest(queueName)).getQueueUrl();

        // The flag used to stop producer, consumer, and monitor threads.
        final AtomicBoolean stop = new AtomicBoolean(false);

        // Start the producers.
        final AtomicInteger producedCount = new AtomicInteger();
        final Thread[] producers = new Thread[producerCount];
        for (int i = 0; i < producerCount; i++) {
            if (batchSize == 1) {
                producers[i] = new Producer(sqsClient, queueUrl, messageSizeByte,
                        producedCount, stop);
            } else {
                producers[i] = new BatchProducer(sqsClient, queueUrl, batchSize,
                        messageSizeByte, producedCount,
                        stop);
            }
            producers[i].start();
        }

        // Start the consumers.
        final AtomicInteger consumedCount = new AtomicInteger();
        final Thread[] consumers = new Thread[consumerCount];
        for (int i = 0; i < consumerCount; i++) {
            if (batchSize == 1) {
                consumers[i] = new Consumer(sqsClient, queueUrl, consumedCount,
                        stop);
            } else {
                consumers[i] = new BatchConsumer(sqsClient, queueUrl, batchSize,
                        consumedCount, stop);
            }
            consumers[i].start();
        }

        // Start the monitor thread.
        final Thread monitor = new Monitor(producedCount, consumedCount, stop);
        monitor.start();

        // Wait for the specified amount of time then stop.
        Thread.sleep(TimeUnit.MINUTES.toMillis(Math.min(runTimeMinutes,
                MAX_RUNTIME_MINUTES)));
        stop.set(true);

        // Join all threads.
        for (int i = 0; i < producerCount; i++) {
            producers[i].join();
        }

        for (int i = 0; i < consumerCount; i++) {
            consumers[i].join();
        }

        monitor.interrupt();
        monitor.join();
    }

    private static String makeRandomString(int sizeByte) {
        final byte[] bs = new byte[(int) Math.ceil(sizeByte * 5 / 8)];
        new Random().nextBytes(bs);
        bs[0] = (byte) ((bs[0] | 64) & 127);
        return new BigInteger(bs).toString(32);
    }

    /**
     * The producer thread uses {@code SendMessage}
     * to send messages until it is stopped.
     */
    private static class Producer extends Thread {
        final AmazonSQS sqsClient;
        final String queueUrl;
        final AtomicInteger producedCount;
        final AtomicBoolean stop;
        final String theMessage;

        Producer(AmazonSQS sqsQueueBuffer, String queueUrl, int messageSizeByte,
                 AtomicInteger producedCount, AtomicBoolean stop) {
            this.sqsClient = sqsQueueBuffer;
            this.queueUrl = queueUrl;
            this.producedCount = producedCount;
            this.stop = stop;
            this.theMessage = makeRandomString(messageSizeByte);
        }

        /*
         * The producedCount object tracks the number of messages produced by
         * all producer threads. If there is an error, the program exits the
         * run() method.
         */
        public void run() {
            try {
                while (!stop.get()) {
                    sqsClient.sendMessage(new SendMessageRequest(queueUrl,
                            theMessage));
                    producedCount.incrementAndGet();
                }
            } catch (AmazonClientException e) {
                /*
                 * By default, AmazonSQSClient retries calls 3 times before
                 * failing. If this unlikely condition occurs, stop.
                 */
                log.error("Producer: " + e.getMessage());
                System.exit(1);
            }
        }
    }

    /**
     * The producer thread uses {@code SendMessageBatch}
     * to send messages until it is stopped.
     */
    private static class BatchProducer extends Thread {
        final AmazonSQS sqsClient;
        final String queueUrl;
        final int batchSize;
        final AtomicInteger producedCount;
        final AtomicBoolean stop;
        final String theMessage;

        BatchProducer(AmazonSQS sqsQueueBuffer, String queueUrl, int batchSize,
                      int messageSizeByte, AtomicInteger producedCount,
                      AtomicBoolean stop) {
            this.sqsClient = sqsQueueBuffer;
            this.queueUrl = queueUrl;
            this.batchSize = batchSize;
            this.producedCount = producedCount;
            this.stop = stop;
            this.theMessage = makeRandomString(messageSizeByte);
        }

        public void run() {
            try {
                while (!stop.get()) {
                    final SendMessageBatchRequest batchRequest =
                            new SendMessageBatchRequest().withQueueUrl(queueUrl);

                    final List<SendMessageBatchRequestEntry> entries =
                            new ArrayList<SendMessageBatchRequestEntry>();
                    for (int i = 0; i < batchSize; i++)
                        entries.add(new SendMessageBatchRequestEntry()
                                .withId(Integer.toString(i))
                                .withMessageBody(theMessage));
                    batchRequest.setEntries(entries);

                    final SendMessageBatchResult batchResult =
                            sqsClient.sendMessageBatch(batchRequest);
                    producedCount.addAndGet(batchResult.getSuccessful().size());

                    /*
                     * Because SendMessageBatch can return successfully, but
                     * individual batch items fail, retry the failed batch items.
                     */
                    if (!batchResult.getFailed().isEmpty()) {
                        log.warn("Producer: retrying sending "
                                + batchResult.getFailed().size() + " messages");
                        for (int i = 0, n = batchResult.getFailed().size();
                             i < n; i++) {
                            sqsClient.sendMessage(new
                                    SendMessageRequest(queueUrl, theMessage));
                            producedCount.incrementAndGet();
                        }
                    }
                }
            } catch (AmazonClientException e) {
                /*
                 * By default, AmazonSQSClient retries calls 3 times before
                 * failing. If this unlikely condition occurs, stop.
                 */
                log.error("BatchProducer: " + e.getMessage());
                System.exit(1);
            }
        }
    }

    /**
     * The consumer thread uses {@code ReceiveMessage} and {@code DeleteMessage}
     * to consume messages until it is stopped.
     */
    private static class Consumer extends Thread {
        final AmazonSQS sqsClient;
        final String queueUrl;
        final AtomicInteger consumedCount;
        final AtomicBoolean stop;

        Consumer(AmazonSQS sqsClient, String queueUrl, AtomicInteger consumedCount,
                 AtomicBoolean stop) {
            this.sqsClient = sqsClient;
            this.queueUrl = queueUrl;
            this.consumedCount = consumedCount;
            this.stop = stop;
        }

        /*
         * Each consumer thread receives and deletes messages until the main
         * thread stops the consumer thread. The consumedCount object tracks the
         * number of messages that are consumed by all consumer threads, and the
         * count is logged periodically.
         */
        public void run() {
            try {
                while (!stop.get()) {
                    try {
                        final ReceiveMessageResult result = sqsClient
                                .receiveMessage(new
                                        ReceiveMessageRequest(queueUrl));

                        if (!result.getMessages().isEmpty()) {
                            final Message m = result.getMessages().get(0);
                            sqsClient.deleteMessage(new
                                    DeleteMessageRequest(queueUrl,
                                    m.getReceiptHandle()));
                            consumedCount.incrementAndGet();
                        }
                    } catch (AmazonClientException e) {
                        log.error(e.getMessage());
                    }
                }
            } catch (AmazonClientException e) {
                /*
                 * By default, AmazonSQSClient retries calls 3 times before
                 * failing. If this unlikely condition occurs, stop.
                 */
                log.error("Consumer: " + e.getMessage());
                System.exit(1);
            }
        }
    }

    /**
     * The consumer thread uses {@code ReceiveMessage} and {@code
     * DeleteMessageBatch} to consume messages until it is stopped.
     */
    private static class BatchConsumer extends Thread {
        final AmazonSQS sqsClient;
        final String queueUrl;
        final int batchSize;
        final AtomicInteger consumedCount;
        final AtomicBoolean stop;

        BatchConsumer(AmazonSQS sqsClient, String queueUrl, int batchSize,
                      AtomicInteger consumedCount, AtomicBoolean stop) {
            this.sqsClient = sqsClient;
            this.queueUrl = queueUrl;
            this.batchSize = batchSize;
            this.consumedCount = consumedCount;
            this.stop = stop;
        }

        public void run() {
            try {
                while (!stop.get()) {
                    final ReceiveMessageResult result = sqsClient
                            .receiveMessage(new ReceiveMessageRequest(queueUrl)
                                    .withMaxNumberOfMessages(batchSize));

                    if (!result.getMessages().isEmpty()) {
                        final List<Message> messages = result.getMessages();
                        final DeleteMessageBatchRequest batchRequest =
                                new DeleteMessageBatchRequest()
                                        .withQueueUrl(queueUrl);

                        final List<DeleteMessageBatchRequestEntry> entries =
                                new ArrayList<DeleteMessageBatchRequestEntry>();
                        for (int i = 0, n = messages.size(); i < n; i++)
                            entries.add(new DeleteMessageBatchRequestEntry()
                                    .withId(Integer.toString(i))
                                    .withReceiptHandle(messages.get(i)
                                            .getReceiptHandle()));
                        batchRequest.setEntries(entries);

                        final DeleteMessageBatchResult batchResult = sqsClient
                                .deleteMessageBatch(batchRequest);
                        consumedCount.addAndGet(batchResult.getSuccessful().size());

                        /*
                         * Because DeleteMessageBatch can return successfully,
                         * but individual batch items fail, retry the failed
                         * batch items.
                         */
                        if (!batchResult.getFailed().isEmpty()) {
                            final int n = batchResult.getFailed().size();
                            log.warn("Producer: retrying deleting " + n
                                    + " messages");
                            for (BatchResultErrorEntry e : batchResult
                                    .getFailed()) {

                                sqsClient.deleteMessage(
                                        new DeleteMessageRequest(queueUrl,
                                                messages.get(Integer
                                                        .parseInt(e.getId()))
                                                        .getReceiptHandle()));

                                consumedCount.incrementAndGet();
                            }
                        }
                    }
                }
            } catch (AmazonClientException e) {
                /*
                 * By default, AmazonSQSClient retries calls 3 times before
                 * failing. If this unlikely condition occurs, stop.
                 */
                log.error("BatchConsumer: " + e.getMessage());
                System.exit(1);
            }
        }
    }

    /**
     * This thread prints every second the number of messages produced and
     * consumed so far.
     */
    private static class Monitor extends Thread {
        private final AtomicInteger producedCount;
        private final AtomicInteger consumedCount;
        private final AtomicBoolean stop;

        Monitor(AtomicInteger producedCount, AtomicInteger consumedCount,
                AtomicBoolean stop) {
            this.producedCount = producedCount;
            this.consumedCount = consumedCount;
            this.stop = stop;
        }

        public void run() {
            try {
                while (!stop.get()) {
                    Thread.sleep(1000);
                    log.info("produced messages = " + producedCount.get()
                            + ", consumed messages = " + consumedCount.get());
                }
            } catch (InterruptedException e) {
                // Allow the thread to exit.
            }
        }
    }
}
```

### Überwachen von Volume-Metriken aus der Beispielausführung
<a name="batch-request-java-example-monitoring-metrics"></a>

Amazon SQS erstellt automatisch Volumen-Metriken für gesendete, empfangene und gelöschte Nachrichten. Auf diese und andere Metriken können Sie über die Registerkarte **Monitoring (Überwachung)** für Ihre Warteschlange oder in der [CloudWatch -Konsole](https://console.aws.amazon.com/cloudwatch/home) zugreifen.

**Anmerkung**  
Nach dem Starten der Warteschlange kann es bis zu 15 Minuten dauern, bis die Metriken verfügbar sind.