管理長時間執行的作業

Google Cloud API 會針對預計需要相當長時間才能完成的呼叫,使用長時間執行的作業 (LRO),例如佈建 Compute Engine 執行個體或初始化 Dataflow 管道。這些 API 不會維持長時間的有效連線,也不會在工作執行期間封鎖。如果是 LRO API,Java 適用的 Cloud 用戶端程式庫會傳回 future,供您稍後檢查。

判斷 API 是否為 LRO

判斷 API 是否為 LRO 的主要方式有兩種:

  • LRO API 的後置字元為 Async (例如 createClusterAsync) 或 OperationCallable (例如 createClusterOperationCallable)。
  • LRO API 會傳回 OperationFutureOperationCallable

下列程式碼片段顯示兩種變體,並以 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()

這兩個是相同 API 的變體,並非兩個不同的 API (兩個呼叫都會建立 Dataproc 叢集)。建議使用 Async 變體。

LRO 的高階流程

LRO API 基本上是先發出初始要求呼叫,然後再發出一連串小型輪詢呼叫。初始呼叫會傳送要求,並在伺服器上建立「作業」。後續對伺服器的所有輪詢呼叫都會追蹤作業狀態。如果作業已完成,系統會傳回回應。 否則會傳回不完整狀態,且用戶端程式庫會判斷是否要再次輪詢。

根據預設,用戶端會處理輪詢邏輯,除非有特定需求,否則您不需要設定輪詢機制。

從您的角度來看,通話會在背景執行,直到收到回應為止。輪詢呼叫和逾時設定都有預設值,服務團隊會根據 API 的預期時間預先設定這些值。這些設定可控制許多因素,例如輪詢頻率和放棄前的等待時間。

Java 適用的 Cloud 用戶端程式庫提供介面,可使用 OperationFuture 與 LRO 互動。

下列程式碼片段說明如何呼叫作業並等待回應,並以 Java-Dataproc 為例:

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.
}

預設 LRO 值

您可以在每個用戶端的 StubSettings 類別中找到預設值。initDefaults() 方法會初始化巢狀 Builder 類別中的 LRO 設定。

舉例來說,在 Java-Aiplatform v3.24.0 中,deployModel LRO 呼叫具有下列預設參數:

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()));

重試和 LRO 共用相同的 RetrySettings 類別。下表顯示 RetrySettings 內欄位與 LRO 功能的對應關係:

RetrySettings 說明
InitialRetryDelay 第一次輪詢前的初始延遲。
MaxRetryDelay 每次輪詢之間的最大延遲時間。
RetryDelayMultiplier 輪詢之間輪詢重試延遲的乘數。
TotalTimeoutDuration 長時間執行的作業允許的最長時間。

設定 LRO 值的時機

手動設定 LRO 值的主要用途是修改輪詢頻率,以解決 LRO 超時問題。雖然預設值是由服務團隊估算而來,但某些因素可能會導致偶爾發生逾時情況。

如要減少逾時次數,請增加總逾時值。增加其他值也有幫助,您應測試這些值,確保行為符合預期。

如何設定 LRO 值

如要設定 LRO 值,請建立 OperationTimedPollAlgorithm 物件,並更新特定 LRO 的輪詢演算法。以下程式碼片段以 Java-Dataproc 為例:

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());

這項設定只會修改 createClusterOperation RPC 的 LRO 值。除非也經過修改,否則用戶端中的其他 RPC 仍會使用每個 RPC 的預先設定 LRO 值。

長時間執行作業逾時

只要未超過總逾時時間,程式庫就會持續輪詢。如果超出總逾時時間,程式庫會擲回 java.util.concurrent.CancellationException,並顯示「工作已取消」訊息。

CancellationException 不代表後端 Google Cloud工作已取消。當呼叫超過總逾時時間且未收到回應時,用戶端程式庫會擲回這項例外狀況。即使工作在逾時後立即完成,用戶端程式庫也不會看到回應。