Google Cloud Le API utilizzano operazioni a lunga esecuzione (LRO) per le chiamate che richiedono un tempo significativo per essere completate (ad esempio, il provisioning di un'istanza Compute Engine o l'inizializzazione di una pipeline Dataflow).
Queste API non mantengono una connessione attiva a lunga durata né bloccano l'esecuzione dell'attività. Per le API LRO, le librerie client Cloud per Java restituiscono un future da controllare in un secondo momento.
Determinare se un'API è un'operazione a lunga esecuzione
Esistono due modi principali per determinare se un'API è un'operazione a lunga esecuzione:
- Le API LRO hanno il suffisso
Async(ad esempio,createClusterAsync) oOperationCallable(ad esempio,createClusterOperationCallable). - Le API LRO restituiscono un
OperationFutureo unOperationCallable.
Il seguente snippet mostra le due varianti, utilizzando Java-Dataproc come esempio:
// 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()
Queste sono due varianti della stessa API e non due API diverse (entrambe le chiamate creano un cluster Managed Service for Apache Spark). È consigliata la variante Async.
Flusso di alto livello di un'operazione a lunga esecuzione
Le API LRO sono essenzialmente una chiamata di richiesta iniziale seguita da una serie di piccole chiamate di polling. La chiamata iniziale invia la richiesta e crea un'operazione sul server. Tutte le chiamate di polling successive al server monitorano lo stato dell'operazione. Se l'operazione è terminata, viene restituita la risposta. In caso contrario, viene restituito uno stato incompleto e la libreria client determina se eseguire di nuovo il polling.
Per impostazione predefinita, il client gestisce la logica di polling e non è necessario configurare il meccanismo di polling, a meno che non siano presenti requisiti specifici.
Dal tuo punto di vista, la chiamata viene eseguita in background fino a quando non viene ricevuta una risposta. Le chiamate di polling e le configurazioni del timeout hanno valori predefiniti preconfigurati dal team del servizio in base al tempo previsto per le relative API. Queste configurazioni controllano molti fattori, ad esempio la frequenza di polling e il tempo di attesa prima di rinunciare.
Le librerie client Cloud per Java forniscono un'interfaccia per interagire con l'operazione a lunga esecuzione utilizzando OperationFuture.
Il seguente snippet mostra come chiamare un'operazione e attendere una risposta, utilizzando Java-Dataproc come esempio:
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.
}
Valori predefiniti delle operazioni a lunga esecuzione
Puoi trovare i valori predefiniti all'interno della classe StubSettings di ogni client. Il metodo initDefaults() inizializza le impostazioni delle operazioni a lunga esecuzione all'interno della classe Builder nidificata.
Ad esempio, in Java-Aiplatform v3.24.0, la chiamata LRO deployModel ha i seguenti parametri predefiniti:
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()));
Sia i nuovi tentativi sia le operazioni a lunga esecuzione condividono la stessa classe RetrySettings. La tabella seguente mostra il mapping tra i campi all'interno di RetrySettings e la funzionalità LRO:
| RetrySettings | Descrizione |
|---|---|
| InitialRetryDelay | Ritardo iniziale prima del primo polling. |
| MaxRetryDelay | Ritardo massimo tra ogni polling. |
| RetryDelayMultiplier | Moltiplicatore per il ritardo di nuovi tentativi di polling tra i polling. |
| TotalTimeoutDuration | Tempo massimo consentito per l'operazione a lunga esecuzione. |
Quando configurare i valori delle operazioni a lunga esecuzione
Il caso d'uso principale per configurare manualmente i valori delle operazioni a lunga esecuzione è modificare le frequenze di polling a causa dei timeout delle operazioni a lunga esecuzione. Sebbene i valori predefiniti siano configurati come stima dal team del servizio, alcuni fattori potrebbero causare timeout occasionali.
Per ridurre il numero di timeout, aumenta il valore del timeout totale. Anche l'aumento degli altri valori può essere utile e devi testarli per garantire il comportamento previsto.
Come configurare i valori delle operazioni a lunga esecuzione
Per configurare i valori delle operazioni a lunga esecuzione, crea un oggetto OperationTimedPollAlgorithm e aggiorna l'algoritmo di polling per una specifica operazione a lunga esecuzione. Il seguente snippet utilizza Java-Dataproc come esempio:
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());
Questa configurazione modifica solo i valori delle operazioni a lunga esecuzione per la RPC createClusterOperation. Le altre RPC nel client utilizzano ancora i valori delle operazioni a lunga esecuzione preconfigurati per ogni RPC, a meno che non vengano modificati.
Timeout delle operazioni a lunga esecuzione
La libreria continua a eseguire il polling finché non viene superato il timeout totale. Se il timeout totale è stato superato, la libreria genera un'eccezione java.util.concurrent.CancellationException con il messaggio "Task was cancelled".
Un CancellationException non significa che l'attività di backend Google Cloud
è stata annullata. Questa eccezione viene generata dalla libreria client quando una chiamata ha superato il timeout totale e non ha ricevuto una risposta. Anche se l'attività viene completata immediatamente dopo il timeout, la risposta non verrà visualizzata dalla libreria client.