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 會傳回
OperationFuture或OperationCallable。
下列程式碼片段顯示兩種變體,並以 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工作已取消。當呼叫超過總逾時時間且未收到回應時,用戶端程式庫會擲回這項例外狀況。即使工作在逾時後立即完成,用戶端程式庫也不會看到回應。