Vorgänge mit langer Ausführungszeit verwalten

Google Cloud APIs verwenden Vorgänge mit langer Ausführungszeit für Aufrufe, bei denen die Ausführung voraussichtlich viel Zeit in Anspruch nehmen wird (z. B. die Bereitstellung einer Compute Engine-Instanz oder die Initialisierung einer Dataflow-Pipeline). Diese APIs halten keine aktive, langlebige Verbindung aufrecht und blockieren nicht, während die Aufgabe ausgeführt wird. Bei APIs mit langer Ausführungszeit geben die Cloud-Clientbibliotheken für Java ein future-Objekt zurück, das Sie später prüfen können.

Feststellen, ob eine API ein Vorgang mit langer Ausführungszeit ist

Es gibt zwei Hauptmethoden, um festzustellen, ob eine API ein Vorgang mit langer Ausführungszeit ist:

  • APIs mit langer Ausführungszeit haben entweder das Suffix Async (z. B. createClusterAsync) oder OperationCallable (z. B. createClusterOperationCallable).
  • APIs mit langer Ausführungszeit geben entweder ein OperationFuture oder OperationCallable zurück.

Das folgende Snippet zeigt die beiden Varianten am Beispiel von Java-Dataproc:

// Async suffix (#1) returns OperationFuture (#2)
public final OperationFuture<Cluster, ClusterOperationMetadata> createClusterAsync(CreateClusterRequest request)

// OperationCallable suffix (#1) returns OperationCallable (#2)
public final OperationCallable<CreateClusterRequest, Cluster, ClusterOperationMetadata> createClusterOperationCallable()

Dies sind zwei Varianten für dieselbe API und nicht zwei verschiedene APIs. Beide Aufrufe erstellen einen Managed Service for Apache Spark-Cluster. Die Variante Async wird empfohlen.

Allgemeiner Ablauf eines Vorgangs mit langer Ausführungszeit

APIs mit langer Ausführungszeit bestehen im Wesentlichen aus einem anfänglichen Aufruf der Anfrage, gefolgt von einer Reihe kleiner Abrufaufrufe. Beim ersten Aufruf wird die Anfrage gesendet und ein Vorgang auf dem Server erstellt. Alle nachfolgenden Abrufaufrufe an den Server verfolgen den Status des Vorgangs. Wenn der Vorgang abgeschlossen ist, wird die Antwort zurückgegeben. Andernfalls wird ein unvollständiger Status zurückgegeben und die Clientbibliothek bestimmt, ob noch einmal abgefragt werden soll.

Standardmäßig verarbeitet der Client die Abruflojik und Sie müssen den Abrufmechanismus nur konfigurieren, wenn Sie bestimmte Anforderungen haben.

Aus Ihrer Sicht wird der Aufruf im Hintergrund ausgeführt, bis eine Antwort eingeht. Die Abrufaufrufe und Zeitüberschreitungskonfigurationen haben Standardwerte, die vom Dienstteam basierend auf der erwarteten Zeit für die APIs vorkonfiguriert werden. Diese Konfigurationen steuern viele Faktoren, z. B. wie oft abgefragt werden soll und wie lange gewartet werden soll, bevor der Vorgang abgebrochen wird.

Die Cloud-Clientbibliotheken für Java bieten eine Schnittstelle für die Interaktion mit dem Vorgang mit langer Ausführungszeit über OperationFuture.

Das folgende Snippet zeigt, wie Sie einen Vorgang aufrufen und auf eine Antwort warten. Als Beispiel wird Java-Dataproc verwendet:

try (ClusterControllerClient clusterControllerClient = ClusterControllerClient.create()) {
  CreateClusterRequest request =
      CreateClusterRequest.newBuilder().build();
  OperationFuture<Cluster, ClusterOperationMetadata> future =
      clusterControllerClient.createClusterAsync(request);
  // Blocks until there is a response
  Cluster response = future.get();
} catch (CancellationException e) {
  // Exceeded the timeout without the Operation completing.
  // Library is no longer polling for the Operation's status.
}

Standardwerte für Vorgänge mit langer Ausführungszeit

Die Standardwerte finden Sie in der Klasse StubSettings jedes Clients. Die Methode initDefaults() initialisiert die Einstellungen für Vorgänge mit langer Ausführungszeit in der verschachtelten Klasse Builder.

In Java-Aiplatform v3.24.0 hat der Aufruf des Vorgangs mit langer Ausführungszeit deployModel beispielsweise die folgenden Standardparameter:

OperationTimedPollAlgorithm.create(
  RetrySettings.newBuilder()
    .setInitialRetryDelayDuration(Duration.ofMillis(5000L))
    .setRetryDelayMultiplier(1.5)
    .setMaxRetryDelayDuration(Duration.ofMillis(45000L))
    .setTotalTimeoutDuration(Duration.ofMillis(300000L))
    .setInitialRpcTimeoutDuration(Duration.ZERO) // not used
    .setRpcTimeoutMultiplier(1.0) // not used
    .setMaxRpcTimeoutDuration(Duration.ZERO) // not used
    .build()));

Sowohl Wiederholungsversuche als auch Vorgänge mit langer Ausführungszeit verwenden dieselbe Klasse RetrySettings. In der folgenden Tabelle wird die Zuordnung zwischen den Feldern in RetrySettings und der Funktionalität für Vorgänge mit langer Ausführungszeit dargestellt:

RetrySettings Beschreibung
InitialRetryDelay Anfängliche Verzögerung vor der ersten Abfrage.
MaxRetryDelay Maximale Verzögerung zwischen den einzelnen Abfragen.
RetryDelayMultiplier Multiplikator für die Verzögerung zwischen den Abfragen.
TotalTimeoutDuration Maximal zulässige Zeit für den Vorgang mit langer Ausführungszeit.

Wann sollten die Werte für Vorgänge mit langer Ausführungszeit konfiguriert werden?

Der Hauptanwendungsfall für die manuelle Konfiguration der Werte für Vorgänge mit langer Ausführungszeit ist die Änderung der Abruffrequenzen aufgrund von Zeitüberschreitungen bei Vorgängen mit langer Ausführungszeit. Die Standardwerte werden vom Dienstteam als Schätzung konfiguriert, aber bestimmte Faktoren können zu gelegentlichen Zeitüberschreitungen führen.

Erhöhen Sie den Wert für die Gesamtdauer der Zeitüberschreitung, um die Anzahl der Zeitüberschreitungen zu reduzieren. Auch das Erhöhen der anderen Werte kann hilfreich sein. Sie sollten sie testen, um das erwartete Verhalten zu gewährleisten.

So konfigurieren Sie die Werte für Vorgänge mit langer Ausführungszeit

Um die Werte für Vorgänge mit langer Ausführungszeit zu konfigurieren, erstellen Sie ein OperationTimedPollAlgorithm-Objekt und aktualisieren Sie den Abrufalgorithmus für einen bestimmten Vorgang mit langer Ausführungszeit. Das folgende Snippet verwendet Java-Dataproc als Beispiel:

ClusterControllerSettings.Builder settingsBuilder = ClusterControllerSettings.newBuilder();
// Create a new OperationTimedPollAlgorithm object
TimedRetryAlgorithm timedRetryAlgorithm = OperationTimedPollAlgorithm.create(
  RetrySettings.newBuilder()
    .setInitialRetryDelayDuration(Duration.ofMillis(500L))
    .setRetryDelayMultiplier(1.5)
    .setMaxRetryDelayDuration(Duration.ofMillis(5000L))
    .setTotalTimeoutDuration(Duration.ofHours(24L))
    .build());
// Set the new polling settings for the specific LRO API 
settingsBuilder.createClusterOperationSettings().setPollingAlgorithm(timedRetryAlgorithm);
ClusterControllerClient clusterControllerClient = ClusterControllerClient.create(settingsBuilder.build());

Diese Konfiguration ändert nur die Werte für Vorgänge mit langer Ausführungszeit für den RPC createClusterOperation. Die anderen RPCs im Client verwenden weiterhin die vorkonfigurierten Werte für Vorgänge mit langer Ausführungszeit für jeden RPC, sofern sie nicht ebenfalls geändert werden.

Zeitüberschreitungen bei Vorgängen mit langer Ausführungszeit

Die Bibliothek fragt so lange ab, bis die Gesamtdauer der Zeitüberschreitung überschritten wurde. Wenn die Gesamtdauer der Zeitüberschreitung überschritten wurde, löst die Bibliothek eine java.util.concurrent.CancellationException mit der Meldung „Task was cancelled“ (Aufgabe wurde abgebrochen) aus.

Eine CancellationException bedeutet nicht, dass die Back-End- Google Cloud Aufgabe abgebrochen wurde. Diese Ausnahme wird von der Clientbibliothek ausgelöst, wenn ein Aufruf die Gesamtdauer der Zeitüberschreitung überschritten hat und keine Antwort erhalten wurde. Auch wenn die Aufgabe unmittelbar nach der Zeitüberschreitung abgeschlossen ist, wird die Antwort von der Clientbibliothek nicht gesehen.