Verwenden Sie asynchrone Programmierung - AWS SDK for Java 2.x

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.

Verwenden Sie asynchrone Programmierung

Es AWS SDK for Java 2.x bietet asynchrone Clients mit nicht blockierender I/O-Unterstützung, die eine hohe Parallelität über einige Threads hinweg implementieren. Eine vollständige blockierungsfreie I/O kann jedoch nicht garantiert werden. In einigen Fällen kann ein asynchroner Client blockierende Aufrufe ausführen, z. B. beim Abrufen von Anmeldeinformationen, beim Signieren von Anfragen mit AWS Signature Version 4 (Sigv4) oder bei der Endpunkterkennung.

Synchrone Methoden blockieren die Ausführung Ihres Threads, bis der Client eine Antwort vom Service erhält. Asynchrone Methoden kehren sofort zurück. So haben Sie die Gewissheit, dass die Kontrolle an den aufrufenden Thread zurückgegeben wird, ohne auf eine Antwort zu warten.

Da eine asynchrone Methode zurückmeldet, bevor eine Antwort verfügbar ist, benötigen Sie einen Weg, an die Antwort zu gelangen, sobald diese bereitsteht. Die Methoden für asynchrone Clients in 2.x der AWS SDK for Java CompletableFuture Rückgabeobjekte, mit denen Sie auf die Antwort zugreifen können, wenn sie bereit ist.

Operationen, die nicht gestreamt werden

Bei Nicht-Streaming-Operationen ähneln asynchrone Methodenaufrufe synchronen Methoden. Die asynchronen Methoden geben jedoch ein CompletableFutureObjekt AWS SDK for Java zurück, das die Ergebnisse des asynchronen Vorgangs in der future enthält.

Rufen Sie die CompletableFuture whenComplete() Methode mit einer Aktion auf, die abgeschlossen werden soll, sobald das Ergebnis verfügbar ist. CompletableFutureimplementiert die Future Schnittstelle, sodass Sie das Antwortobjekt auch abrufen können, indem Sie die get() Methode aufrufen.

Im Folgenden finden Sie ein Beispiel für eine asynchrone Operation, bei der eine Amazon DynamoDB Funktion aufgerufen wird, um eine Liste von Tabellen abzurufen, wobei eine Tabelle empfangen wird, CompletableFuture die ein ListTablesResponseObjekt enthalten kann. Die im Aufruf von whenComplete() definierte Aktion wird nur ausgeführt, wenn der asynchrone Aufruf abgeschlossen ist.

Importe

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient; import software.amazon.awssdk.services.dynamodb.model.ListTablesRequest; import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse; import java.util.List; import java.util.concurrent.CompletableFuture;

Code

public class DynamoDBAsyncListTables { public static void main(String[] args) throws InterruptedException { // Create the DynamoDbAsyncClient object Region region = Region.US_EAST_1; DynamoDbAsyncClient client = DynamoDbAsyncClient.builder() .region(region) .build(); listTables(client); } public static void listTables(DynamoDbAsyncClient client) { CompletableFuture<ListTablesResponse> response = client.listTables(ListTablesRequest.builder() .build()); // Map the response to another CompletableFuture containing just the table names CompletableFuture<List<String>> tableNames = response.thenApply(ListTablesResponse::tableNames); // When future is complete (either successfully or in error) handle the response tableNames.whenComplete((tables, err) -> { try { if (tables != null) { tables.forEach(System.out::println); } else { // Handle error err.printStackTrace(); } } finally { // Lets the application shut down. Only close the client when you are completely done with it. client.close(); } }); tableNames.join(); } }

Im folgenden Codebeispiel wird gezeigt, wie ein Element mithilfe des asynchronen Clients aus einer Tabelle abgerufen wird. Rufen Sie die getItem Methode von auf DynamoDbAsyncClient und übergeben Sie ihr ein GetItemRequestObjekt mit dem Tabellennamen und dem Primärschlüsselwert des gewünschten Elements. Dies ist in der Regel, wie Sie Daten übergeben, die für den Vorgang erforderlich sind. Beachten Sie in diesem Beispiel, dass ein Zeichenfolgenwert übergeben wird.

Importe

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.dynamodb.model.GetItemRequest; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;

Code

public static void getItem(DynamoDbAsyncClient client, String tableName, String key, String keyVal) { HashMap<String, AttributeValue> keyToGet = new HashMap<String, AttributeValue>(); keyToGet.put(key, AttributeValue.builder() .s(keyVal).build()); try { // Create a GetItemRequest instance GetItemRequest request = GetItemRequest.builder() .key(keyToGet) .tableName(tableName) .build(); // Invoke the DynamoDbAsyncClient object's getItem java.util.Collection<AttributeValue> returnedItem = client.getItem(request).join().item().values(); // Convert Set to Map Map<String, AttributeValue> map = returnedItem.stream().collect(Collectors.toMap(AttributeValue::s, s->s)); Set<String> keys = map.keySet(); for (String sinKey : keys) { System.out.format("%s: %s\n", sinKey, map.get(sinKey).toString()); } } catch (DynamoDbException e) { System.err.println(e.getMessage()); System.exit(1); }

Das vollständige Beispiel finden Sie unter. GitHub

Streaming-Operationen

Für Streaming-Operationen müssen Sie eine angeben, AsyncRequestBodyum den Inhalt inkrementell bereitzustellen, oder eine, AsyncResponseTransformerum die Antwort zu empfangen und zu verarbeiten.

Im folgenden Beispiel wird mithilfe des Vorgangs eine Datei Amazon S3 asynchron in hochgeladen. PutObject

Importe

import software.amazon.awssdk.core.async.AsyncRequestBody; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.s3.S3AsyncClient; import software.amazon.awssdk.services.s3.model.PutObjectRequest; import software.amazon.awssdk.services.s3.model.PutObjectResponse; import java.nio.file.Paths; import java.util.concurrent.CompletableFuture;

Code

/** * To run this AWS code example, ensure that you have setup your development environment, including your AWS credentials. * * For information, see this documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class S3AsyncOps { public static void main(String[] args) { final String USAGE = "\n" + "Usage:\n" + " S3AsyncOps <bucketName> <key> <path>\n\n" + "Where:\n" + " bucketName - the name of the Amazon S3 bucket (for example, bucket1). \n\n" + " key - the name of the object (for example, book.pdf). \n" + " path - the local path to the file (for example, C:/AWS/book.pdf). \n" ; if (args.length != 3) { System.out.println(USAGE); System.exit(1); } String bucketName = args[0]; String key = args[1]; String path = args[2]; Region region = Region.US_WEST_2; S3AsyncClient client = S3AsyncClient.builder() .region(region) .build(); PutObjectRequest objectRequest = PutObjectRequest.builder() .bucket(bucketName) .key(key) .build(); // Put the object into the bucket CompletableFuture<PutObjectResponse> future = client.putObject(objectRequest, AsyncRequestBody.fromFile(Paths.get(path)) ); future.whenComplete((resp, err) -> { try { if (resp != null) { System.out.println("Object uploaded. Details: " + resp); } else { // Handle error err.printStackTrace(); } } finally { // Only close the client when you are completely done with it client.close(); } }); future.join(); } }

Im folgenden Beispiel wird mithilfe des Vorgangs eine Datei Amazon S3 asynchron abgerufen. GetObject

Importe

import software.amazon.awssdk.core.async.AsyncResponseTransformer; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.s3.S3AsyncClient; import software.amazon.awssdk.services.s3.model.GetObjectRequest; import software.amazon.awssdk.services.s3.model.GetObjectResponse; import java.nio.file.Paths; import java.util.concurrent.CompletableFuture;

Code

/** * To run this AWS code example, ensure that you have setup your development environment, including your AWS credentials. * * For information, see this documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class S3AsyncStreamOps { public static void main(String[] args) { final String USAGE = "\n" + "Usage:\n" + " S3AsyncStreamOps <bucketName> <objectKey> <path>\n\n" + "Where:\n" + " bucketName - the name of the Amazon S3 bucket (for example, bucket1). \n\n" + " objectKey - the name of the object (for example, book.pdf). \n" + " path - the local path to the file (for example, C:/AWS/book.pdf). \n" ; if (args.length != 3) { System.out.println(USAGE); System.exit(1); } String bucketName = args[0]; String objectKey = args[1]; String path = args[2]; Region region = Region.US_WEST_2; S3AsyncClient client = S3AsyncClient.builder() .region(region) .build(); GetObjectRequest objectRequest = GetObjectRequest.builder() .bucket(bucketName) .key(objectKey) .build(); CompletableFuture<GetObjectResponse> futureGet = client.getObject(objectRequest, AsyncResponseTransformer.toFile(Paths.get(path))); futureGet.whenComplete((resp, err) -> { try { if (resp != null) { System.out.println("Object downloaded. Details: "+resp); } else { err.printStackTrace(); } } finally { // Only close the client when you are completely done with it client.close(); } }); futureGet.join(); } }

Fortgeschrittene Operationen

AWS SDK for Java 2.x verwendet Netty, ein asynchrones, ereignisgesteuertes Netzwerkanwendungs-Framework, um I/O-Threads zu verarbeiten. AWS SDK for Java 2.x erstellt ein ExecutorService Back-Netty, um die von der Client-Anfrage bis zum HTTP Netty-Client zurückgegebenen Futures zu vervollständigen. Diese Abstraktion reduziert das Risiko, dass eine Anwendung den asynchronen Prozess unterbricht, wenn Entwickler Threads anhalten oder in den Ruhezustand versetzen. Standardmäßig erstellt jeder asynchrone Client einen Threadpool, der auf der Anzahl der Prozessoren basiert, und verwaltet die Aufgaben in einer Warteschlange innerhalb von. ExecutorService

Fortgeschrittene Benutzer können ihre Thread-Pool-Größe beim Erstellen eines asynchronen Clients mit der folgenden Option beim Erstellen angeben.

Code

S3AsyncClient clientThread = S3AsyncClient.builder() .asyncConfiguration( b -> b.advancedOption(SdkAdvancedAsyncClientOption .FUTURE_COMPLETION_EXECUTOR, Executors.newFixedThreadPool(10) ) ) .build();

Um die Leistung zu optimieren, können Sie Ihren eigenen Thread-Pool-Executor verwalten und ihn bei der Konfiguration Ihres Clients einschließen.

ThreadPoolExecutor executor = new ThreadPoolExecutor(50, 50, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>(<custom_value>), new ThreadFactoryBuilder() .threadNamePrefix("sdk-async-response").build()); // Allow idle core threads to time out executor.allowCoreThreadTimeOut(true); S3AsyncClient clientThread = S3AsyncClient.builder() .asyncConfiguration( b -> b.advancedOption(SdkAdvancedAsyncClientOption .FUTURE_COMPLETION_EXECUTOR, executor ) ) .build();