Freigeben über


Lang andauernde Vorgänge im Azure SDK für Java

Dieser Artikel enthält eine Übersicht über die Verwendung langer Vorgänge mit dem Azure SDK für Java.

Bestimmte Vorgänge in Azure können längere Zeit in Anspruch nehmen. Diese Vorgänge befinden sich außerhalb des standardmäßigen HTTP-Stils des Schnellanforderungs-/Antwortflusses. Beispielsweise sind das Kopieren von Daten aus einer Quell-URL in ein Speicher-Blob oder das Trainieren eines Modells zum Erkennen von Formularen Vorgänge, die einige Sekunden bis zu mehreren Minuten dauern können. Solche Vorgänge werden als Long-Running Vorgänge bezeichnet und werden häufig als "LRO" abgekürzt. Je nach angeforderter Operation und dem Prozess, der auf der Serverseite ausgeführt werden muss, kann ein LRO Sekunden, Minuten, Stunden, Tage oder länger dauern.

In den Java-Clientbibliotheken für Azure gibt es eine Konvention, dass alle lang ausgeführten Vorgänge mit dem begin Präfix beginnen. Dieses Präfix gibt an, dass dieser Vorgang lang ausgeführt wird und dass sich die Interaktion mit diesem Vorgang geringfügig von dem üblichen Anforderungs-/Antwortfluss unterscheidet. Zusammen mit dem begin Präfix unterscheidet sich der Rückgabetyp des Vorgangs ebenfalls von den üblichen, um die gesamte Palette von Funktionen für lang andauernde Vorgänge zu aktivieren. Wie bei den meisten Dingen im Azure SDK für Java gibt es sowohl synchrone als auch asynchrone APIs für lange ausgeführte Vorgänge:

  • In synchronen Client-Anwendungen geben langlaufende Vorgänge eine SyncPoller Instanz zurück.
  • Bei asynchronen Clients geben zeitintensive Vorgänge eine PollerFlux-Instanz zurück.

Sowohl SyncPoller als auch PollerFlux sind die clientseitigen Abstraktionen, die die Interaktion mit lang andauernden serverseitigen Vorgängen vereinfachen sollen. Im restlichen Artikel werden bewährte Methoden beim Arbeiten mit diesen Typen beschrieben.

Synchrone zeitintensive Vorgänge

Beim Aufrufen einer API, die eine SyncPoller zurückgibt, wird die lang andauernde Operation sofort gestartet. Die API gibt sofort SyncPoller zurück, sodass Sie den Fortschritt des lang ausgeführten Vorgangs überwachen und das Endergebnis abrufen können. Das folgende Beispiel zeigt, wie der Fortschritt eines lang andauernden Vorgangs mithilfe der SyncPoller überwacht werden kann.

SyncPoller<UploadBlobProgress, UploadedBlobProperties> poller = syncClient.beginUploadFromUri(<URI to upload from>)
PollResponse<UploadBlobProgress> response;

do {
    response = poller.poll();
    System.out.println("Status of long running upload operation: " + response.getStatus());
    Duration pollInterval = response.getRetryAfter();
    TimeUnit.MILLISECONDS.sleep(pollInterval.toMillis());
} while (!response.getStatus().isComplete());

In diesem Beispiel wird die poll() Methode auf SyncPoller verwendet, um Informationen zum Fortschritt des lang andauernden Vorgangs abzurufen. Dieser Code druckt den Status in der Konsole, aber eine bessere Implementierung würde relevante Entscheidungen basierend auf diesem Status treffen.

Die getRetryAfter() Methode gibt Informationen dazu zurück, wie lange vor der nächsten Abfrage gewartet werden soll. Die meisten lang ausgeführten Azure-Vorgänge geben die Abfrageverzögerung als Teil ihrer HTTP-Antwort zurück (d. h. den häufig verwendeten retry-after Header). Wenn die Antwort die Abrufverzögerung nicht enthält, gibt die getRetryAfter()-Methode die Dauer zurück, die zum Zeitpunkt des Aufrufs des zeitintensiven Vorgangs angegeben wurde.

Im obigen Beispiel wird eine do..while-Schleife verwendet, um wiederholt abzufragen, bis die lang andauernde Operation abgeschlossen ist. Wenn Sie nicht an diesen Zwischenergebnissen interessiert sind, können Sie stattdessen anrufen waitForCompletion(). Dieser Aufruf blockiert den aktuellen Thread, bis der lange ausgeführte Vorgang abgeschlossen ist, und gibt die letzte Umfrageantwort zurück:

PollResponse<UploadBlobProgress> response = poller.waitForCompletion();

Wenn die letzte Abfrageantwort anzeigt, dass der zeitintensive Vorgang erfolgreich abgeschlossen wurde, können Sie das Endergebnis mithilfe von getFinalResult() abrufen:

if (LongRunningOperationStatus.SUCCESSFULLY_COMPLETED == response.getStatus()) {
    UploadedBlobProperties result = poller.getFinalResult();
}

In SyncPoller finden sich weitere nützliche APIs:

  1. waitForCompletion(Duration): Wartet für die angegebene Timeoutdauer auf den Abschluss des zeitintensiven Vorgangs.
  2. waitUntil(LongRunningOperationStatus): Wartet, bis der angegebene Status des zeitintensiven Vorgangs empfangen wurde.
  3. waitUntil(LongRunningOperationStatus, Duration): Wartet, bis der angegebene Status des zeitintensiven Vorgangs empfangen wurde, oder bis die angegebene Timeoutdauer abgelaufen ist.

Asynchrone zeitintensive Vorgänge

Das folgende Beispiel zeigt, wie Sie mit PollerFlux einen langdauernden Vorgang beobachten können. In asynchronen APIs erfolgen die Netzwerkaufrufe in einem anderen Thread als im Hauptthread, der subscribe() aufruft. Dies bedeutet, dass der Hauptthread beendet werden kann, bevor das Ergebnis verfügbar ist. Es liegt an Ihnen, sicherzustellen, dass die Anwendung nicht beendet wird, bevor der asynchrone Vorgang abgeschlossen wurde.

Die asynchrone API gibt PollerFlux sofort zurück, aber der langandauernde Vorgang selbst startet erst, wenn Sie den PollerFlux abonnieren. Dieser Prozess ist die Funktionsweise aller Flux-basierten APIs. Das folgende Beispiel zeigt einen asynchronen lang andauernden Vorgang.

asyncClient.beginUploadFromUri(...)
    .subscribe(response -> System.out.println("Status of long running upload operation: " + response.getStatus()));

Im folgenden Beispiel erhalten Sie regelmäßige Statusupdates über den lang andauernden Vorgang. Sie können diese Updates verwenden, um zu bestimmen, ob der lange ausgeführte Vorgang weiterhin erwartungsgemäß funktioniert. Mit diesem Beispiel wird der Status in der Konsole ausgegeben, aber eine bessere Implementierung würde relevante Entscheidungen zur Fehlerbehandlung auf Grundlage dieses Status treffen.

Wenn Sie nicht an den Zwischenstatusaktualisierungen interessiert sind und nur beim Eintreffen über das Endergebnis benachrichtigt werden möchten, können Sie Code wie im folgenden Beispiel verwenden:

asyncClient.beginUploadFromUri(...)
    .last()
    .flatMap(response -> {
        if (LongRunningOperationStatus.SUCCESSFULLY_COMPLETED == response.getStatus()) {
            return response.getFinalResult();
        }
        return Mono.error(new IllegalStateException("Polling completed unsuccessfully with status: "+ response.getStatus()));
    })
    .subscribe(
        finalResult -> processFormPages(finalResult),
        ex -> countDownLatch.countDown(),
        () -> countDownLatch.countDown());

In diesem Code erhalten Sie das Endergebnis des lange ausgeführten Vorgangs durch das Aufrufen von last(). Dieser Aufruf teilt dem PollerFlux mit, dass Sie auf den Abschluss aller Abrufe warten möchten. Zu diesem Zeitpunkt hat dann der zeitintensive Vorgang einen Endzustand erreicht, und Sie können seinen Status überprüfen, um das Ergebnis zu bestimmen. Wenn der Poller anzeigt, dass der zeitintensive Vorgang erfolgreich abgeschlossen wurde, können Sie das Endergebnis abrufen und an den Consumer im subscribe-Aufruf übergeben.

Nächste Schritte

Nachdem Sie nun mit den langfristig ausgeführten APIs im Azure SDK für Java vertraut sind, lesen Sie "Konfigurieren von Proxies im Azure SDK für Java", um zu erfahren, wie Sie den HTTP-Client weiter anpassen können.