Asynchrone Programmierung - AWS SDK for Java 1.x

Wir haben die bevorstehende end-of-support für AWS SDK for Java (v1) angekündigt. Wir empfehlen Ihnen, zu AWS SDK for Java v2 zu migrieren. Datumsangaben, zusätzliche Details und Informationen zur Migration finden Sie in der verlinkten Ankündigung.

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.

Asynchrone Programmierung

Sie können entweder synchrone oder asynchrone Methoden verwenden, um -Operationen auf - AWS Services aufzurufen. 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 AWS SDK for Java bietet zwei Möglichkeiten: Zukünftige Objekte und Rückrufmethoden.

Java-Futures

Asynchrone Methoden im AWS SDK for Java geben ein future-Objekt zurück, das die Ergebnisse der asynchronen Operation in der future enthält.

Rufen Sie die Future isDone()-Methode auf, um festzustellen, ob der Service bereits ein Antwortobjekt bereitgestellt hat. Wenn die Antwort bereit ist, können Sie das Antwortobjekt durch Aufrufen der Future get()-Methode erhalten. Mit diesem Mechanismus können Sie regelmäßig eine Abfrage nach den Ergebnissen der asynchronen Operation durchführen, während die Anwendung an anderen Aufgaben arbeitet.

Hier ist ein Beispiel für eine asynchrone Operation, die eine - Lambda Funktion aufruft und ein empfängtFuture, das ein InvokeResult Objekt enthalten kann. Das InvokeResult-Objekt wird erst abgerufen, sobald isDone() true ergibt.

import com.amazonaws.services.lambda.AWSLambdaAsyncClient; import com.amazonaws.services.lambda.model.InvokeRequest; import com.amazonaws.services.lambda.model.InvokeResult; import java.nio.ByteBuffer; import java.util.concurrent.Future; import java.util.concurrent.ExecutionException; public class InvokeLambdaFunctionAsync { public static void main(String[] args) { String function_name = "HelloFunction"; String function_input = "{\"who\":\"SDK for Java\"}"; AWSLambdaAsync lambda = AWSLambdaAsyncClientBuilder.defaultClient(); InvokeRequest req = new InvokeRequest() .withFunctionName(function_name) .withPayload(ByteBuffer.wrap(function_input.getBytes())); Future<InvokeResult> future_res = lambda.invokeAsync(req); System.out.print("Waiting for future"); while (future_res.isDone() == false) { System.out.print("."); try { Thread.sleep(1000); } catch (InterruptedException e) { System.err.println("\nThread.sleep() was interrupted!"); System.exit(1); } } try { InvokeResult res = future_res.get(); if (res.getStatusCode() == 200) { System.out.println("\nLambda function returned:"); ByteBuffer response_payload = res.getPayload(); System.out.println(new String(response_payload.array())); } else { System.out.format("Received a non-OK response from {AWS}: %d\n", res.getStatusCode()); } } catch (InterruptedException | ExecutionException e) { System.err.println(e.getMessage()); System.exit(1); } System.exit(0); } }

Asynchrone Callbacks

Zusätzlich zur Verwendung des Java-FutureObjekts zur Überwachung des Status asynchroner Anforderungen ermöglicht Ihnen das SDK auch die Implementierung einer Klasse, die die -AsyncHandlerSchnittstelle verwendet. AsyncHandler bietet zwei Methoden, die je nachdem aufgerufen werden, wie die Anforderung abgeschlossen wurde: onSuccess und onError.

Der wichtigste Vorteil der Rückruf-Schnittstelle besteht darin, dass Sie das Future-Objekt nicht mehr regelmäßig abfragen müssen, um zu ermitteln, wann die Anforderung abgeschlossen wurde. Stattdessen kann Ihr Code sofort die nächste Aktivität beginnen und sich auf das SDK verlassen, das für den Aufruf Ihrer Handler zum richtigen Zeitpunkt sorgt.

import com.amazonaws.services.lambda.AWSLambdaAsync; import com.amazonaws.services.lambda.AWSLambdaAsyncClientBuilder; import com.amazonaws.services.lambda.model.InvokeRequest; import com.amazonaws.services.lambda.model.InvokeResult; import com.amazonaws.handlers.AsyncHandler; import java.nio.ByteBuffer; import java.util.concurrent.Future; public class InvokeLambdaFunctionCallback { private class AsyncLambdaHandler implements AsyncHandler<InvokeRequest, InvokeResult> { public void onSuccess(InvokeRequest req, InvokeResult res) { System.out.println("\nLambda function returned:"); ByteBuffer response_payload = res.getPayload(); System.out.println(new String(response_payload.array())); System.exit(0); } public void onError(Exception e) { System.out.println(e.getMessage()); System.exit(1); } } public static void main(String[] args) { String function_name = "HelloFunction"; String function_input = "{\"who\":\"SDK for Java\"}"; AWSLambdaAsync lambda = AWSLambdaAsyncClientBuilder.defaultClient(); InvokeRequest req = new InvokeRequest() .withFunctionName(function_name) .withPayload(ByteBuffer.wrap(function_input.getBytes())); Future<InvokeResult> future_res = lambda.invokeAsync(req, new AsyncLambdaHandler()); System.out.print("Waiting for async callback"); while (!future_res.isDone() && !future_res.isCancelled()) { // perform some other tasks... try { Thread.sleep(1000); } catch (InterruptedException e) { System.err.println("Thread.sleep() was interrupted!"); System.exit(0); } System.out.print("."); } } }

Bewährte Methoden

Ausführen eines Rückrufs

Ihre Implementierung des AsyncHandler wird in dem Threadpool ausgeführt, der dem asynchronen Client gehört. Der kurze, schnell ausgeführte Code sollte am besten in der AsyncHandler-Implementierung eingefügt werden. Der lange ausgeführte oder blockierende Code in Handler-Methoden kann zu Konkurrenzsituationen für den Threadpool, der vom asynchronen Client verwendet wird, und kann den Client daran hindern, Anforderungen auszuführen. Wenn Sie eine lang andauernde Aufgabe haben, die mit einem Rückruf gestartet werden soll, lassen Sie den Rückruf die Aufgabe in einem neuen Thread oder in einem Threadpool ausführen, der von Ihrer Anwendung verwaltet wird.

Threadpool-Konfiguration

Die asynchronen Clients in der AWS SDK for Java bieten einen Standard-Threadpool, der für die meisten Anwendungen funktionieren sollte. Sie können einen benutzerdefinierten implementieren ExecutorService und ihn an AWS SDK for Java asynchrone Clients übergeben, um mehr Kontrolle über die Verwaltung der Thread-Pools zu erhalten.

Sie können beispielsweise eine ExecutorService Implementierung bereitstellen, die einen benutzerdefinierten verwendet, ThreadFactory um zu steuern, wie Threads im Pool benannt werden, oder um zusätzliche Informationen zur Thread-Nutzung zu protokollieren.

Asynchroner Zugriff

Die TransferManager Klasse im SDK bietet asynchrone Unterstützung für die Arbeit mit Amazon S3. TransferManager verwaltet asynchrone Uploads und Downloads, bietet detaillierte Fortschrittsberichte zu Übertragungen und unterstützt Rückrufe für verschiedene Ereignisse.