重試策略

本頁面說明 Cloud Storage 工具如何重試失敗的要求,以及如何自訂重試行為。此外,本文也會說明重試要求時的注意事項。

總覽

有兩個因素會決定要求是否可安全重試:

  • 您從要求收到的回應

  • 要求的冪等性

回應

您從要求收到的回應會指出是否值得重試要求。與暫時性問題相關的回應通常可以重試。另一方面,永久錯誤相關的回應表示您需要進行變更 (例如授權或設定變更),才能再次嘗試要求。下列回應表示暫時性問題,建議重試:

  • HTTP 4084295xx 回應代碼。
  • 通訊端逾時和 TCP 中斷連線。

詳情請參閱 JSONXML 的狀態和錯誤代碼。

冪等

冪等要求可重複執行,不會改變目標資源的最終狀態,每次都會產生相同的最終狀態。舉例來說,清單作業一律為等冪,因為這類要求不會修改資源。另一方面,建立新的 Pub/Sub 通知絕不會是等冪作業,因為每次要求成功時,系統都會建立新的通知 ID。

以下是讓作業具備等冪性的條件範例:

  • 即使持續要求,這項作業對目標資源產生的可觀察效果仍相同。

  • 這項作業只會成功一次。

  • 這項作業對目標資源的狀態沒有可觀察到的影響。

收到可重試的回應時,請考慮要求的等冪性,因為重試非等冪要求可能會導致競爭情況和其他衝突。

條件式冪等性

部分要求是有條件的等冪,也就是說,只有在包含特定選用引數時,要求才會是等冪。如果作業在特定條件下可安全重試,只有在條件成立時,系統才會預設重試。Cloud Storage 接受先決條件和 ETag 做為要求的條件案例。

作業的冪等性

下表列出各類冪等性的 Cloud Storage 作業。

冪等 作業
一律為等冪
  • 所有 get 和 list 要求
  • 插入或刪除值區
  • 測試 bucket 身分與存取權管理政策和權限
  • 鎖定保留政策
  • 刪除 HMAC 金鑰或 Pub/Sub 通知
有條件等冪
  • 針對具有 IfMetagenerationMatch1etag1 的 bucket 提出更新/修補要求時,HTTP 先決條件
  • IfMetagenerationMatch1etag1 做為 HTTP 先決條件,更新/修補物件的要求
  • 使用 etag1 做為 HTTP 前置條件或資源主體,設定 bucket IAM 政策
  • 使用 etag1 做為 HTTP 前置條件或資源主體,更新 HMAC 金鑰
  • 使用 ifGenerationMatch1 插入、複製、編寫或重寫物件
  • 使用 ifGenerationMatch1 刪除物件 (或使用物件版本的產生編號)
永不具備等冪性
  • 建立 HMAC 金鑰
  • 建立 Pub/Sub 通知
  • 建立、刪除或傳送值區和物件 ACL 或預設物件 ACL 的 patch/update 要求

1這個欄位可用於 JSON API。如要瞭解用戶端程式庫可使用的欄位,請參閱相關的用戶端程式庫說明文件

Cloud Storage 工具如何實作重試策略

控制台

Google Cloud 控制台會代表您向 Cloud Storage 傳送要求,並處理所有必要的輪詢。

指令列

gcloud storage 指令會重試「回應」一節中列出的錯誤,您不必採取其他動作。您可能需要針對其他錯誤採取行動,例如:

  • 憑證無效或權限不足。

  • Proxy 設定有問題,因此無法連上網路。

如果發生可重試的錯誤,gcloud CLI 會使用部分二進位指數輪詢策略重試要求。gcloud CLI 的預設重試次數上限為 32 次。

用戶端程式庫

C++

根據預設,作業支援下列 HTTP 錯誤碼的重試,以及任何表示連線中斷或從未成功建立的通訊端錯誤。

  • 408 Request Timeout
  • 429 Too Many Requests
  • 500 Internal Server Error
  • 502 Bad Gateway
  • 503 Service Unavailable
  • 504 Gateway Timeout

C++ 程式庫中的所有指數輪詢和重試設定都可以設定。如果程式庫中實作的演算法無法滿足您的需求,您可以提供自訂程式碼來實作自己的策略。

設定 預設值
自動重試
重試要求的時間上限 15 分鐘
初始等待 (輪詢) 時間 1 秒
每次疊代的等待時間乘數 2
等待時間上限 5 分鐘

根據預設,C++ 程式庫會重試所有作業,即使作業從未具備等冪性,且重複成功時可能會刪除或建立多個資源,也會重試。如要只重試等冪作業,請使用 google::cloud::storage::StrictIdempotencyPolicy 類別。

C#

C# 用戶端程式庫預設使用指數輪詢

Go

根據預設,作業支援下列錯誤的重試作業:

  • 連線錯誤:
    • io.ErrUnexpectedEOF:這可能是暫時性網路問題所致。
    • url.Error 含有 connection refused:這可能是暫時性的網路問題所致。
    • 包含 connection reset by peerurl.Error: 這表示 Google Cloud 已重設連線。
    • net.ErrClosed:這表示 Google Cloud 已關閉連線。
  • HTTP 程式碼:
    • 408 Request Timeout
    • 429 Too Many Requests
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout
  • 實作 Temporary() 介面並提供 err.Temporary() == true 值的錯誤
  • 使用 Go 1.13 錯誤包裝包裝的上述任一錯誤

Go 程式庫中的所有指數輪詢設定皆可設定。 根據預設,Go 中的作業會使用下列設定進行指數輪詢 (預設值取自 gax):

設定 預設值 (以秒為單位)
自動重試 如果是冪等,則為 True
嘗試次數上限 不限
初始重試延遲 1 秒
重試延遲時間乘數 2.0
重試延遲時間上限 30 秒
總逾時 (可續傳的上傳區塊) 32 秒
總逾時 (所有其他作業) 不限

一般來說,除非控制環境已取消、用戶端已關閉或收到非暫時性錯誤,否則系統會無限期重試。如要停止重試,請使用內容逾時或取消。使用 Writer 執行可續傳的上傳作業時,如果資料量夠大,需要多個要求,就會發生例外狀況。在此情境中,每個區塊預設會在 32 秒後逾時,並停止重試。您可以變更 Writer.ChunkRetryDeadline,調整預設逾時時間。

部分 Go 作業是條件式等冪 (可安全地重試)。只有在符合特定條件時,這些作業才會重試:

  • GenerationMatchGeneration

    • 如果對呼叫套用了 GenerationMatch 前置條件,或已設定 ObjectHandle.Generation,則可安全地重試。
  • MetagenerationMatch

    • 如果通話套用了 MetagenerationMatch 前置條件,可以安全地重試。
  • Etag

    • 如果方法會在 JSON 要求主體中插入 etag,則可以安全地重試。僅在已設定 HmacKeyMetadata.Etag 時,用於 HMACKeyHandle.Update

RetryPolicy 預設為 RetryPolicy.RetryIdempotent。如要瞭解如何修改預設重試行為,請參閱「自訂重試」一文中的範例。

Java

根據預設,作業支援下列錯誤的重試作業:

  • 連線錯誤:
    • Connection reset by peer:這表示 Google Cloud 已重設連線。
    • Unexpected connection closure:這表示 Google Cloud 已關閉連線。
  • HTTP 程式碼:
    • 408 Request Timeout
    • 429 Too Many Requests
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout

Java 程式庫中的所有指數輪詢設定都可以設定。根據預設,透過 Java 執行的作業會使用下列指數輪詢設定:

設定 預設值 (以秒為單位)
自動重試 如果是冪等,則為 True
嘗試次數上限 6
初始重試延遲 1 秒
重試延遲時間乘數 2.0
重試延遲時間上限 32 秒
總逾時 50 秒
初始遠端程序呼叫 (RPC) 逾時 50 秒
遠端程序呼叫 (RPC) 逾時乘數 1.0
遠端程序呼叫 (RPC) 逾時上限 50 秒
連線逾時 20 秒
讀取逾時 20 秒

如要進一步瞭解相關設定,請參閱 RetrySettings.BuilderHttpTransportOptions.Builder 的 Java 參考說明文件。

部分 Java 作業是條件式等冪 (條件式安全重試)。只有在包含特定引數時,這些作業才會重試:

  • ifGenerationMatchgeneration

    • 如果 ifGenerationMatchgeneration 已做為方法選項傳遞,可以安全地重試。
  • ifMetagenerationMatch

    • 如果 ifMetagenerationMatch 是以選項形式傳入,則可安全地重試。

StorageOptions.setStorageRetryStrategy 預設為 StorageRetryStrategy#getDefaultStorageRetryStrategy。如需修改預設重試行為的範例,請參閱「自訂重試」。

Node.js

根據預設,作業支援下列錯誤代碼的重試作業:

  • 連線錯誤:
    • EAI_again:這是 DNS 查詢錯誤。詳情請參閱 getaddrinfo 說明文件
    • Connection reset by peer:這表示 Google Cloud 已重設連線。
    • Unexpected connection closure:這表示 Google Cloud 已關閉連線。
  • HTTP 程式碼:
    • 408 Request Timeout
    • 429 Too Many Requests
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout

Node.js 程式庫中的所有指數輪詢設定都可以設定。 根據預設,透過 Node.js 執行的作業會使用下列指數輪詢設定:

設定 預設值 (以秒為單位)
自動重試 如果是冪等,則為 True
重試次數上限 3
初始等待時間 1 秒
每次疊代的等待時間乘數 2
等待時間上限 64 秒
預設截止日期 600 秒

部分 Node.js 作業是條件式等冪 (條件式安全重試)。只有在包含特定引數時,這些作業才會重試:

  • ifGenerationMatchgeneration

    • 如果 ifGenerationMatchgeneration 已做為方法選項傳遞,可以安全地重試。方法通常只接受其中一個參數。
  • ifMetagenerationMatch

    • 如果 ifMetagenerationMatch 是以選項形式傳入,則可安全地重試。

retryOptions.idempotencyStrategy 預設為 IdempotencyStrategy.RetryConditional。如要瞭解如何修改預設重試行為,請參閱「自訂重試」一文中的範例。

PHP

PHP 用戶端程式庫預設使用指數輪詢

Python

根據預設,作業支援下列錯誤代碼的重試作業:

  • 連線錯誤:
    • requests.exceptions.ConnectionError
    • requests.exceptions.ChunkedEncodingError (僅適用於擷取或傳送酬載資料至物件的作業,例如上傳和下載)
    • ConnectionError
    • http.client.ResponseNotReady
    • urllib3.exceptions.TimeoutError
  • HTTP 程式碼:
    • 408 Request Timeout
    • 429 Too Many Requests
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout

透過 Python 執行的作業會使用下列指數輪詢預設設定:

設定 預設值 (以秒為單位)
自動重試 如果是冪等,則為 True
初始等待時間 1
每次疊代的等待時間乘數 2
等待時間上限 60
預設截止日期 120

除了一律為等冪的 Cloud Storage 作業外,Python 用戶端程式庫預設會自動重試 Objects: insertObjects: deleteObjects: patch

如果包含特定引數,部分 Python 作業會成為有條件的等冪作業 (可安全地重試)。只有在條件案例通過時,這些作業才會重試:

  • DEFAULT_RETRY_IF_GENERATION_SPECIFIED

    • 如果 generationif_generation_match 已做為引數傳入方法,則可安全地重試。方法通常只接受這兩個參數的其中一個。
  • DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED

    • 如果 if_metageneration_match 已做為方法引數傳入,可以安全地重試。
  • DEFAULT_RETRY_IF_ETAG_IN_JSON

    • 如果方法會在 JSON 要求主體中插入 etag,則可以安全地重試。對於 HMACKeyMetadata.update(),這表示必須在 HMACKeyMetadata 物件本身設定 etag。如果是其他類別的 set_iam_policy() 方法,則表示必須在傳遞至該方法的「policy」引數中設定 etag。

Ruby

根據預設,作業支援下列錯誤代碼的重試作業:

  • 連線錯誤:
    • SocketError
    • HTTPClient::TimeoutError
    • Errno::ECONNREFUSED
    • HTTPClient::KeepAliveDisconnected
  • HTTP 程式碼:
    • 408 Request Timeout
    • 429 Too Many Requests
    • 5xx Server Error

Ruby 用戶端程式庫中的所有指數輪詢設定都是可設定的。Ruby 用戶端程式庫預設會使用下列設定,透過指數輪詢執行作業:

設定 預設值
自動重試
重試次數上限 3
初始等待時間 1 秒
每次疊代的等待時間乘數 2
等待時間上限 60 秒
預設截止日期 900 秒

如果 Ruby 作業包含特定引數,則屬於條件式等冪作業 (可安全地重試):

  • if_generation_matchgeneration

    • 如果 generationif_generation_match 參數做為引數傳遞至方法,可以安全地重試。方法通常只接受這兩個參數之一。
  • if_metageneration_match

    • 如果 if_metageneration_match 參數以選項形式傳入,可以安全地重試。

根據預設,系統會重試所有等冪作業,且只有在條件案例通過時,才會重試有條件的等冪作業。系統不會重試非冪等作業。如要瞭解如何修改預設重試行為,請參閱「自訂重試」一文中的範例。

REST API

直接呼叫 JSON 或 XML API 時,應使用指數輪詢演算法,自行實作重試策略。

自訂重試次數

控制台

您無法使用 Google Cloud 控制台自訂重試行為。

指令列

如果是 gcloud storage 指令,您可以建立具名設定,並設定下列部分或所有屬性,藉此控管重試策略:

設定 預設值 (以秒為單位)
base_retry_delay 1
exponential_sleep_multiplier 2
max_retries 32
max_retry_delay 32

接著,您可以透過--configuration 專案範圍標記,為每個指令套用定義的設定,也可以使用 gcloud config set 指令,為所有 Google Cloud CLI 指令套用設定。

用戶端程式庫

C++

如要自訂重試行為,請在初始化 google::cloud::storage::Client 物件時,為下列選項提供值:

  • google::cloud::storage::RetryPolicyOption:這個程式庫提供 google::cloud::storage::LimitedErrorCountRetryPolicygoogle::cloud::storage::LimitedTimeRetryPolicy 類別。您可以提供自己的類別,但必須實作 google::cloud::RetryPolicy 介面。

  • google::cloud::storage::BackoffPolicyOption:這個程式庫提供 google::cloud::storage::ExponentialBackoffPolicy 類別。您可以提供自己的類別,但必須實作 google::cloud::storage::BackoffPolicy 介面。

  • google::cloud::storage::IdempotencyPolicyOption:這個程式庫提供 google::cloud::storage::StrictIdempotencyPolicygoogle::cloud::storage::AlwaysRetryIdempotencyPolicy 類別。您可以提供自己的類別,但必須實作 google::cloud::storage::IdempotencyPolicy 介面。

詳情請參閱 C++ 用戶端程式庫參考說明文件

namespace gcs = ::google::cloud::storage;
// Create the client configuration:
auto options = google::cloud::Options{};
// Retries only idempotent operations.
options.set<gcs::IdempotencyPolicyOption>(
    gcs::StrictIdempotencyPolicy().clone());
// On error, it backs off for a random delay between [1, 3] seconds, then [3,
// 9] seconds, then [9, 27] seconds, etc. The backoff time never grows larger
// than 1 minute.
options.set<gcs::BackoffPolicyOption>(
    gcs::ExponentialBackoffPolicy(
        /*initial_delay=*/std::chrono::seconds(1),
        /*maximum_delay=*/std::chrono::minutes(1),
        /*scaling=*/3.0)
        .clone());
// Retries all operations for up to 5 minutes, including any backoff time.
options.set<gcs::RetryPolicyOption>(
    gcs::LimitedTimeRetryPolicy(std::chrono::minutes(5)).clone());
return gcs::Client(std::move(options));

C#

您無法自訂 C# 用戶端程式庫使用的預設重試策略。

Go

初始化儲存空間用戶端時,系統會設定預設重試設定。除非覆寫,否則設定中的選項會設為預設值。使用者可以為單一程式庫呼叫 (使用 BucketHandle.RetryerObjectHandle.Retryer) 或用戶端發出的所有呼叫 (使用 Client.SetRetry),設定非預設的重試行為。如要修改重試行為,請將相關的 RetryOptions 傳遞至下列其中一種方法。

請參閱下列程式碼範例,瞭解如何自訂重試行為。

import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/storage"
	"github.com/googleapis/gax-go/v2"
)

// configureRetries configures a custom retry strategy for a single API call.
func configureRetries(w io.Writer, bucket, object string) error {
	// bucket := "bucket-name"
	// object := "object-name"
	ctx := context.Background()
	client, err := storage.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("storage.NewClient: %w", err)
	}
	defer client.Close()

	// Configure retries for all operations using this ObjectHandle. Retries may
	// also be configured on the BucketHandle or Client types.
	o := client.Bucket(bucket).Object(object).Retryer(
		// Use WithBackoff to control the timing of the exponential backoff.
		storage.WithBackoff(gax.Backoff{
			// Set the initial retry delay to a maximum of 2 seconds. The length of
			// pauses between retries is subject to random jitter.
			Initial: 2 * time.Second,
			// Set the maximum retry delay to 60 seconds.
			Max: 60 * time.Second,
			// Set the backoff multiplier to 3.0.
			Multiplier: 3,
		}),
		// Use WithPolicy to customize retry so that all requests are retried even
		// if they are non-idempotent.
		storage.WithPolicy(storage.RetryAlways),
	)

	// Use context timeouts to set an overall deadline on the call, including all
	// potential retries.
	ctx, cancel := context.WithTimeout(ctx, 500*time.Second)
	defer cancel()

	// Delete an object using the specified retry policy.
	if err := o.Delete(ctx); err != nil {
		return fmt.Errorf("Object(%q).Delete: %w", object, err)
	}
	fmt.Fprintf(w, "Blob %v deleted with a customized retry strategy.\n", object)
	return nil
}

Java

初始化 Storage 時,系統也會初始化 RetrySettings 的執行個體。除非遭到覆寫,否則 RetrySettings 中的選項會設為預設值。如要修改預設的自動重試行為,請將自訂的 StorageRetryStrategy 傳遞至用於建構 Storage 執行個體的 StorageOptions。如要修改任何其他純量參數,請將自訂 RetrySettings 傳遞至用於建構 Storage 例項的 StorageOptions

請參閱以下範例,瞭解如何自訂重試行為:


import com.google.api.gax.retrying.RetrySettings;
import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import com.google.cloud.storage.StorageRetryStrategy;
import org.threeten.bp.Duration;

public final class ConfigureRetries {
  public static void main(String[] args) {
    String bucketName = "my-bucket";
    String blobName = "blob/to/delete";
    deleteBlob(bucketName, blobName);
  }

  static void deleteBlob(String bucketName, String blobName) {
    // Customize retry behavior
    RetrySettings retrySettings =
        StorageOptions.getDefaultRetrySettings().toBuilder()
            // Set the max number of attempts to 10 (initial attempt plus 9 retries)
            .setMaxAttempts(10)
            // Set the backoff multiplier to 3.0
            .setRetryDelayMultiplier(3.0)
            // Set the max duration of all attempts to 5 minutes
            .setTotalTimeout(Duration.ofMinutes(5))
            .build();

    StorageOptions alwaysRetryStorageOptions =
        StorageOptions.newBuilder()
            // Customize retry so all requests are retried even if they are non-idempotent.
            .setStorageRetryStrategy(StorageRetryStrategy.getUniformStorageRetryStrategy())
            // provide the previously configured retrySettings
            .setRetrySettings(retrySettings)
            .build();

    // Instantiate a client
    Storage storage = alwaysRetryStorageOptions.getService();

    // Delete the blob
    BlobId blobId = BlobId.of(bucketName, blobName);
    boolean success = storage.delete(blobId);

    System.out.printf(
        "Deletion of Blob %s completed %s.%n", blobId, success ? "successfully" : "unsuccessfully");
  }
}

Node.js

初始化 Cloud Storage 時,系統也會初始化 retryOptions 設定檔。除非覆寫,否則設定中的選項會設為預設值。如要修改預設的重試行為,請在初始化時,將自訂重試設定 retryOptions 傳遞至儲存空間建構函式。Node.js 用戶端程式庫可自動使用輪詢策略,重試具有 autoRetry 參數的要求。

請參閱下列程式碼範例,瞭解如何自訂重試行為。

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The ID of your GCS file
// const fileName = 'your-file-name';

// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage({
  retryOptions: {
    // If this is false, requests will not retry and the parameters
    // below will not affect retry behavior.
    autoRetry: true,
    // The multiplier by which to increase the delay time between the
    // completion of failed requests, and the initiation of the subsequent
    // retrying request.
    retryDelayMultiplier: 3,
    // The total time between an initial request getting sent and its timeout.
    // After timeout, an error will be returned regardless of any retry attempts
    // made during this time period.
    totalTimeout: 500,
    // The maximum delay time between requests. When this value is reached,
    // retryDelayMultiplier will no longer be used to increase delay time.
    maxRetryDelay: 60,
    // The maximum number of automatic retries attempted before returning
    // the error.
    maxRetries: 5,
    // Will respect other retry settings and attempt to always retry
    // conditionally idempotent operations, regardless of precondition
    idempotencyStrategy: IdempotencyStrategy.RetryAlways,
  },
});
console.log(
  'Functions are customized to be retried according to the following parameters:'
);
console.log(`Auto Retry: ${storage.retryOptions.autoRetry}`);
console.log(
  `Retry delay multiplier: ${storage.retryOptions.retryDelayMultiplier}`
);
console.log(`Total timeout: ${storage.retryOptions.totalTimeout}`);
console.log(`Maximum retry delay: ${storage.retryOptions.maxRetryDelay}`);
console.log(`Maximum retries: ${storage.retryOptions.maxRetries}`);
console.log(
  `Idempotency strategy: ${storage.retryOptions.idempotencyStrategy}`
);

async function deleteFileWithCustomizedRetrySetting() {
  await storage.bucket(bucketName).file(fileName).delete();
  console.log(`File ${fileName} deleted with a customized retry strategy.`);
}

deleteFileWithCustomizedRetrySetting();

PHP

您無法自訂 PHP 用戶端程式庫使用的預設重試策略。

Python

如要修改預設重試行為,請呼叫 with_XXX 方法,建立 google.cloud.storage.retry.DEFAULT_RETRY 物件的副本。如果您加入 DEFAULT_RETRY 參數,Python 用戶端程式庫會自動使用輪詢策略重試要求。

請注意,系統不支援對物件擷取或傳送酬載資料的作業 (例如上傳和下載)。with_predicate建議您逐一修改屬性。詳情請參閱 google-api-core Retry 參考資料

如要設定自己的條件式重試,請建立 ConditionalRetryPolicy 物件,並使用 DEFAULT_RETRY_IF_GENERATION_SPECIFIEDDEFAULT_RETRY_IF_METAGENERATION_SPECIFIEDDEFAULT_RETRY_IF_ETAG_IN_JSON 包裝自訂 Retry 物件。

請參閱下列程式碼範例,瞭解如何自訂重試行為。

from google.cloud import storage
from google.cloud.storage.retry import DEFAULT_RETRY


def configure_retries(bucket_name, blob_name):
    """Configures retries with customizations."""
    # The ID of your GCS bucket
    # bucket_name = "your-bucket-name"
    # The ID of your GCS object
    # blob_name = "your-object-name"

    storage_client = storage.Client()
    bucket = storage_client.bucket(bucket_name)
    blob = bucket.blob(blob_name)

    # Customize retry with a timeout of 500 seconds (default=120 seconds).
    modified_retry = DEFAULT_RETRY.with_timeout(500.0)
    # Customize retry with an initial wait time of 1.5 (default=1.0).
    # Customize retry with a wait time multiplier per iteration of 1.2 (default=2.0).
    # Customize retry with a maximum wait time of 45.0 (default=60.0).
    modified_retry = modified_retry.with_delay(initial=1.5, multiplier=1.2, maximum=45.0)

    # blob.delete() uses DEFAULT_RETRY by default.
    # Pass in modified_retry to override the default retry behavior.
    print(
        f"The following library method is customized to be retried according to the following configurations: {modified_retry}"
    )

    blob.delete(retry=modified_retry)
    print(f"Blob {blob_name} deleted with a customized retry strategy.")

Ruby

初始化儲存空間用戶端時,所有重試設定都會設為上表顯示的值。如要修改預設重試行為,請在初始化儲存空間用戶端時傳遞重試設定。

如要覆寫特定作業的重試次數,請在作業的 options 參數中傳遞 retries

def configure_retries bucket_name: nil, file_name: nil
  # The ID of your GCS bucket
  # bucket_name = "your-unique-bucket-name"

  # The ID of your GCS object
  # file_name = "your-file-name"

  require "google/cloud/storage"

  # Creates a client
  storage = Google::Cloud::Storage.new(

    # The maximum number of automatic retries attempted before returning
    # the error.
    #
    # Customize retry configuration with the maximum retry attempt of 5.
    retries: 5,

    # The total time in seconds that requests are allowed to keep being retried.
    # After max_elapsed_time, an error will be returned regardless of any
    # retry attempts made during this time period.
    #
    # Customize retry configuration with maximum elapsed time of 500 seconds.
    max_elapsed_time: 500,

    # The initial interval between the completion of failed requests, and the
    # initiation of the subsequent retrying request.
    #
    # Customize retry configuration with an initial interval of 1.5 seconds.
    base_interval: 1.5,

    # The maximum interval between requests. When this value is reached,
    # multiplier will no longer be used to increase the interval.
    #
    # Customize retry configuration with maximum interval of 45.0 seconds.
    max_interval: 45,

    # The multiplier by which to increase the interval between the completion
    # of failed requests, and the initiation of the subsequent retrying request.
    #
    # Customize retry configuration with an interval multiplier per iteration of 1.2.
    multiplier: 1.2
  )

  # Uses the retry configuration set during the client initialization above with 5 retries
  file = storage.service.get_file bucket_name, file_name

  # Maximum retry attempt can be overridden for each operation using options parameter.
  storage.service.delete_file bucket_name, file_name, options: { retries: 4 }
  puts "File #{file.name} deleted with a customized retry strategy."
end

REST API

使用「指數輪詢」演算法,實作自己的重試策略。

指數輪詢演算法

指數輪詢演算法會以指數方式重試要求,並將每次要求之間的等待時間逐漸增加至最大輪詢時間,一般來說,您應使用指數輪詢和抖動,重試符合回應和等冪條件的要求。如要瞭解如何以指數輪詢方式自動重試,請參閱解決連鎖故障問題

重試反模式

建議您視情況使用或自訂內建重試機制;請參閱自訂重試。無論您是使用預設重試機制、自訂機制,還是實作自己的重試邏輯,都必須避免下列常見的反模式,因為這些模式可能會加劇問題,而非解決問題。

不輪詢直接重試

立即重試要求或延遲時間很短,可能會導致連鎖性故障,也就是說,故障可能會觸發其他故障。

如何避免這個問題:實作指數輪詢和抖動。這項策略會逐步增加重試之間的等待時間,並加入隨機元素,避免重試次數過多導致服務過載。

無條件重試非等冪作業

重複執行非等冪作業可能會導致非預期的副作用,例如非預期的資料覆寫或刪除。

如何避免這個問題:請詳閱「作業的等冪性」一節,徹底瞭解各項作業的等冪性特徵。對於非等冪作業,請確保重試邏輯可以處理潛在的重複項目,或完全避免重試。請謹慎重試,以免導致競爭狀況。

重試無法重試的錯誤

將所有錯誤視為可重試的錯誤可能會造成問題。舉例來說,授權失敗或無效要求等錯誤會持續發生,如果未解決根本原因就重試,將不會成功,且可能導致應用程式陷入無限迴圈。

如何避免這種情況:將錯誤分為暫時性 (可重試) 和永久性 (不可重試)。請只重試暫時性錯誤,例如 4084295xx HTTP 代碼,或特定連線問題。如果是永久性錯誤,請記錄下來並妥善處理根本原因。

忽略重試次數上限

無限期重試可能會導致應用程式耗盡資源,或持續向不會自行復原的服務傳送要求。

如何避免這種情況:根據工作負載的性質調整重試次數上限。如為對延遲時間較敏感的工作負載,請考慮設定重試時間上限,確保及時回應或失敗。如果是批次工作負載,可能可以容許暫時性伺服器端錯誤的重試時間較長,建議您設定較高的重試次數上限。

不必要地分層重試

在現有的重試機制上新增自訂應用程式層級的重試邏輯,可能會導致重試次數過多。舉例來說,如果應用程式重試作業三次,而基礎用戶端程式庫也會針對應用程式的每次嘗試重試三次,您最終可能會重試九次。如果針對無法重試的錯誤傳送大量重試要求,可能會導致要求遭到節流,進而限制所有工作負載的輸送量。重試次數過多也可能導致要求延遲,但成功率不會提高。

如何避免這種情況:建議您使用及設定內建的重試機制。如果必須實作應用程式層級的重試機制 (例如針對跨多項作業的特定商業邏輯),請務必清楚瞭解底層的重試行為。建議您在其中一個層級中停用或大幅限制重試次數,避免乘法效應。

後續步驟