Strategi percobaan ulang

Halaman ini menjelaskan cara alat Cloud Storage mencoba ulang permintaan yang gagal dan cara menyesuaikan perilaku percobaan ulang. Bagian ini juga menjelaskan pertimbangan dalam mencoba ulang permintaan.

Ringkasan

Ada dua faktor yang menentukan apakah sebuah permintaan aman untuk dicoba ulang:

  • Respons yang Anda terima dari permintaan.

  • Idempotensi permintaan.

Tanggapan

Respons yang Anda terima dari permintaan menunjukkan apakah akan berguna untuk mencoba ulang permintaan tersebut. Respons yang terkait dengan masalah sementara umumnya dapat dicoba ulang. Di sisi lain, respons yang terkait dengan error permanen menunjukkan bahwa Anda perlu melakukan perubahan, seperti perubahan otorisasi atau konfigurasi, sebelum mencoba ulang permintaan tersebut. Respons berikut menunjukkan masalah sementara yang akan berguna jika Anda mencoba ulang permintaan:

  • Kode respons HTTP 408, 429, dan 5xx.
  • Waktu tunggu soket dan TCP terputus.

Untuk mengetahui informasi selengkapnya, lihat kode status dan error untuk JSON dan XML.

Idempotensi

Permintaan yang idempoten dapat dieksekusi berulang kali tanpa mengubah status akhir resource yang ditargetkan, sehingga menghasilkan status akhir yang sama setiap kali. Misalnya, operasi daftar selalu bersifat idempoten, karena permintaan tersebut tidak mengubah resource. Di sisi lain, pembuatan notifikasi Pub/Sub baru tidak pernah bersifat idempoten, karena permintaan tersebut akan membuat ID notifikasi baru setiap kali permintaan berhasil.

Berikut adalah contoh kondisi yang membuat operasi menjadi bersifat idempoten:

  • Operasi memiliki efek yang dapat diamati yang sama pada resource yang ditargetkan, bahkan saat operasi tersebut terus diminta.

  • Operasi hanya berhasil satu kali.

  • Operasi tidak memiliki efek yang dapat diamati pada status resource yang ditargetkan.

Saat menerima respons yang dapat dicoba ulang, Anda harus mempertimbangkan idempotensi permintaan, karena mencoba ulang permintaan yang tidak idempoten dapat menyebabkan kondisi race dan konflik lainnya.

Idempotensi bersyarat

Subset permintaan bersifat bersifat idempoten bersyarat, yang berarti permintaan tersebut hanya idempoten jika menyertakan argumen opsional tertentu. Operasi yang dapat dicoba ulang secara bersyarat hanya boleh dicoba ulang secara default jika kasus kondisi terpenuhi. Cloud Storage menerima prasyarat dan ETag sebagai kasus kondisi untuk permintaan.

Idempotensi operasi

Tabel berikut mencantumkan operasi Cloud Storage yang termasuk dalam setiap kategori keidempotenan.

Idempotensi Operations
Selalu bersifat idempoten
  • Semua permintaan dapatkan dan buat daftar
  • Menyisipkan atau menghapus bucket
  • Menguji kebijakan dan izin IAM bucket
  • Penguncian kebijakan retensi
  • Menghapus kunci HMAC atau notifikasi Pub/Sub
Idempotensi bersyarat
  • Permintaan update/patch untuk bucket dengan IfMetagenerationMatch1 atau etag1 sebagai prasyarat HTTP
  • Permintaan update/patch untuk objek dengan IfMetagenerationMatch1 atau etag1 sebagai prasyarat HTTP
  • Menetapkan kebijakan IAM bucket dengan etag1 sebagai prasyarat HTTP atau di isi resource
  • Memperbarui kunci HMAC dengan etag1 sebagai prasyarat HTTP atau di isi resource
  • Menyisipkan, menyalin, menyusun, atau menulis ulang objek dengan ifGenerationMatch1
  • Menghapus objek dengan ifGenerationMatch1 (atau dengan nomor generasi untuk versi objek)
Tidak pernah bersifat idempoten
  • Membuat kunci HMAC
  • Membuat notifikasi Pub/Sub
  • Membuat, menghapus, atau mengirim permintaan patch/update untuk ACL bucket dan objek atau ACL objek default

1Kolom ini tersedia untuk digunakan di JSON API. Untuk mengetahui kolom yang tersedia untuk digunakan di library klien, lihat dokumentasi library klien yang relevan.

Cara alat Cloud Storage mengimplementasikan strategi percobaan ulang

Konsol

Konsol Google Cloud mengirim permintaan ke Cloud Storage atas nama Anda dan menangani semua jeda yang diperlukan.

Command line

Perintah gcloud storage mencoba ulang error yang tercantum di bagian Respons tanpa mengharuskan Anda melakukan tindakan tambahan. Anda mungkin harus mengambil tindakan untuk error lainnya, seperti berikut ini:

  • Kredensial tidak valid atau izin tidak memadai.

  • Jaringan tidak dapat dijangkau karena masalah konfigurasi proxy.

Untuk error yang dapat dicoba ulang, gcloud CLI mencoba ulang permintaan menggunakan strategi backoff eksponensial biner yang terpotong. Jumlah maksimum percobaan ulang default adalah 32 untuk gcloud CLI.

Library klien

C++

Secara default, operasi mendukung percobaan ulang untuk kode error HTTP berikut, serta error soket yang menunjukkan bahwa koneksi terputus atau tidak pernah berhasil dibuat.

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

Semua setelan backoff eksponensial dan percobaan ulang di library C++ dapat dikonfigurasi. Jika algoritma yang diimplementasikan dalam library tidak mendukung kebutuhan Anda, Anda dapat memberikan kode kustom untuk mengimplementasikan strategi Anda sendiri.

Setelan Nilai default
Percobaan ulang otomatis Benar
Waktu maksimum untuk percobaan ulang permintaan 15 menit
Waktu tunggu (backoff) awal 1 detik
Pengganda waktu tunggu per iterasi 2
Jumlah waktu tunggu maksimum 5 menit

Secara default, library C++ akan mencoba ulang semua operasi yang memiliki error yang dapat dicoba ulang, bahkan untuk operasi yang tidak pernah idempoten dan dapat menghapus atau membuat beberapa resource jika berhasil berulang kali. Untuk mencoba ulang operasi idempoten saja, gunakan kelas google::cloud::storage::StrictIdempotencyPolicy.

C#

Library klien C# menggunakan backoff eksponensial secara default.

Go

Secara default, operasi mendukung percobaan ulang untuk error berikut ini:

  • Error koneksi:
    • io.ErrUnexpectedEOF: Hal ini dapat terjadi karena masalah jaringan yang bersifat sementara.
    • url.Error yang berisi connection refused: Hal ini dapat terjadi karena masalah jaringan yang bersifat sementara.
    • url.Error yang berisi connection reset by peer: Ini berarti Google Cloud telah mereset koneksi.
    • net.ErrClosed: Ini berarti Google Cloud telah menutup koneksi.
  • Kode HTTP:
    • 408 Request Timeout
    • 429 Too Many Requests
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout
  • Error yang mengimplementasikan antarmuka Temporary() dan memberikan nilai err.Temporary() == true
  • Error di atas yang telah di-wrap menggunakan pembungkusan error Go 1.13

Semua setelan mundur eksponensial di library Go dapat dikonfigurasi. Secara default, operasi di Go menggunakan setelan berikut untuk penundaan eksponensial (nilai default diambil dari gax):

Setelan Nilai default (dalam detik)
Percobaan ulang otomatis True jika idempoten
Jumlah maksimum upaya Tak terbatas
Penundaan percobaan ulang awal 1 detik
Pengganda penundaan percobaan ulang 2.0
Penundaan percobaan ulang maksimum 30 seconds
Total waktu tunggu (bagian dari upload yang dapat dilanjutkan) 32 detik
Total waktu tunggu (semua operasi lainnya) Tak terbatas

Secara umum, percobaan ulang akan berlanjut tanpa batas waktu kecuali jika konteks pengendalian dibatalkan, klien ditutup, atau terjadi error yang bersifat non-sementara. Untuk menghentikan percobaan ulang agar tidak berlanjut, gunakan waktu tunggu konteks atau pembatalan. Satu-satunya pengecualian untuk perilaku ini adalah saat melakukan upload yang dapat dilanjutkan menggunakan Writer, dengan data yang cukup besar sehingga memerlukan beberapa permintaan. Dalam skenario ini, waktu tunggu setiap bagian akan habis dan berhenti mencoba ulang setelah 32 detik secara default. Anda dapat menyesuaikan waktu tunggu default dengan mengubah Writer.ChunkRetryDeadline.

Ada sebagian operasi Go yang idempoten bersyarat (aman untuk dicoba ulang dalam kondisi tertentu). Operasi ini hanya akan dicoba ulang jika memenuhi kondisi tertentu:

  • GenerationMatch atau Generation

    • Aman untuk dicoba ulang jika prasyarat GenerationMatch diterapkan ke panggilan, atau jika ObjectHandle.Generation ditetapkan.
  • MetagenerationMatch

    • Aman untuk dicoba ulang jika prasyarat MetagenerationMatch diterapkan ke panggilan.
  • Etag

    • Aman untuk dicoba ulang jika metode menyisipkan etag ke dalam isi permintaan JSON. Hanya digunakan di HMACKeyHandle.Update jika HmacKeyMetadata.Etag telah ditetapkan.

RetryPolicy ditetapkan ke RetryPolicy.RetryIdempotent secara default. Lihat Menyesuaikan percobaan ulang untuk mengetahui contoh cara mengubah perilaku percobaan ulang default.

Java

Secara default, operasi mendukung percobaan ulang untuk error berikut ini:

  • Error koneksi:
    • Connection reset by peer: Hal ini berarti Google Cloud telah mereset koneksi.
    • Unexpected connection closure: Artinya, Google Cloud telah menutup koneksi.
  • Kode HTTP:
    • 408 Request Timeout
    • 429 Too Many Requests
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout

Semua setelan jeda eksponensial di library Java dapat dikonfigurasi. Secara default, operasi melalui Java menggunakan setelan berikut untuk backoff eksponensial:

Setelan Nilai default (dalam detik)
Percobaan ulang otomatis True jika idempoten
Jumlah maksimum upaya 6
Penundaan percobaan ulang awal 1 detik
Pengganda penundaan percobaan ulang 2.0
Penundaan percobaan ulang maksimum 32 detik
Total Waktu Tunggu 50 detik
Waktu Tunggu RPC Awal 50 detik
Pengali Waktu Tunggu RPC 1.0
Waktu Tunggu RPC Maksimum 50 detik
Waktu Tunggu Koneksi 20 detik
Waktu Tunggu Baca 20 detik

Untuk mengetahui informasi selengkapnya tentang setelan, lihat dokumentasi referensi Java untuk RetrySettings.Builder dan HttpTransportOptions.Builder.

Ada sebagian operasi Java yang idempoten bersyarat (aman untuk dicoba ulang dalam kondisi tertentu). Operasi tersebut hanya melakukan percobaan ulang jika menyertakan argumen tertentu:

  • ifGenerationMatch atau generation

    • Aman untuk dicoba ulang jika ifGenerationMatch atau generation diteruskan sebagai opsi ke metode ini.
  • ifMetagenerationMatch

    • Aman untuk dicoba ulang jika ifMetagenerationMatch diteruskan sebagai opsi.

StorageOptions.setStorageRetryStrategy ditetapkan ke StorageRetryStrategy#getDefaultStorageRetryStrategy secara default. Lihat Menyesuaikan percobaan ulang untuk mengetahui contoh cara mengubah perilaku percobaan ulang default.

Node.js

Secara default, operasi mendukung percobaan ulang untuk kode error berikut ini:

  • Error koneksi:
    • EAI_again: Ini adalah error pencarian DNS. Untuk mengetahui informasi selengkapnya, lihat dokumentasi getaddrinfo.
    • Connection reset by peer: Hal ini berarti Google Cloud telah mereset koneksi.
    • Unexpected connection closure: Artinya, Google Cloud telah menutup koneksi.
  • Kode HTTP:
    • 408 Request Timeout
    • 429 Too Many Requests
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout

Semua setelan penundaan eksponensial di library Node.js dapat dikonfigurasi. Secara default, operasi melalui Node.js menggunakan setelan berikut untuk penundaan eksponensial:

Setelan Nilai default (dalam detik)
Percobaan ulang otomatis True jika idempoten
Jumlah maksimum percobaan ulang 3
Waktu tunggu awal 1 detik
Pengganda waktu tunggu per iterasi 2
Jumlah waktu tunggu maksimum 64 detik
Batas waktu default 600 detik

Ada sebagian operasi Node.js yang idempoten bersyarat (aman untuk dicoba ulang dalam kondisi tertentu). Operasi tersebut hanya melakukan percobaan ulang jika menyertakan argumen tertentu:

  • ifGenerationMatch atau generation

    • Aman untuk dicoba ulang jika ifGenerationMatch atau generation diteruskan sebagai opsi ke metode ini. Sering kali, metode hanya menerima salah satu dari dua parameter ini.
  • ifMetagenerationMatch

    • Aman untuk dicoba ulang jika ifMetagenerationMatch diteruskan sebagai opsi.

retryOptions.idempotencyStrategy ditetapkan ke IdempotencyStrategy.RetryConditional secara default. Lihat Menyesuaikan percobaan ulang untuk mengetahui contoh cara mengubah perilaku percobaan ulang default.

PHP

Library klien PHP menggunakan penundaan eksponensial secara default.

Python

Secara default, operasi mendukung percobaan ulang untuk kode error berikut ini:

  • Error koneksi:
    • requests.exceptions.ConnectionError
    • requests.exceptions.ChunkedEncodingError (hanya untuk operasi yang mengambil atau mengirim data payload ke objek, seperti upload dan download)
    • ConnectionError
    • http.client.ResponseNotReady
    • urllib3.exceptions.TimeoutError
  • Kode HTTP:
    • 408 Request Timeout
    • 429 Too Many Requests
    • 500 Internal Server Error
    • 502 Bad Gateway
    • 503 Service Unavailable
    • 504 Gateway Timeout

Operasi melalui Python menggunakan setelan default berikut untuk penundaan eksponensial:

Setelan Nilai default (dalam detik)
Percobaan ulang otomatis True jika idempoten
Waktu tunggu awal 1
Pengganda waktu tunggu per iterasi 2
Jumlah waktu tunggu maksimum 60
Batas waktu default 120

Selain operasi Cloud Storage yang selalu bersifat idempoten, library klien Python secara otomatis mencoba kembali Objects: insert, Objects: delete, dan Objects: patch secara default.

Ada sebagian operasi Python yang idempoten bersyarat (aman untuk dicoba ulang dalam kondisi tertentu) saat menyertakan argumen tertentu. Operasi ini hanya akan dicoba ulang jika kasus kondisi terpenuhi:

  • DEFAULT_RETRY_IF_GENERATION_SPECIFIED

    • Aman untuk dicoba ulang jika generation atau if_generation_match diteruskan sebagai argumen ke metode. Sering kali metode hanya menerima salah satu dari dua parameter ini.
  • DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED

    • Aman untuk dicoba ulang jika if_metageneration_match diteruskan sebagai argumen ke metode.
  • DEFAULT_RETRY_IF_ETAG_IN_JSON

    • Aman untuk dicoba ulang jika metode menyisipkan etag ke dalam isi permintaan JSON. Untuk HMACKeyMetadata.update(), ini berarti ETag harus ditetapkan pada objek HMACKeyMetadata itu sendiri. Untuk metode set_iam_policy() di kelas lain, ini berarti ETag harus ditetapkan dalam argumen "kebijakan" yang diteruskan ke metode.

Ruby

Secara default, operasi mendukung percobaan ulang untuk kode error berikut ini:

  • Error koneksi:
    • SocketError
    • HTTPClient::TimeoutError
    • Errno::ECONNREFUSED
    • HTTPClient::KeepAliveDisconnected
  • Kode HTTP:
    • 408 Request Timeout
    • 429 Too Many Requests
    • 5xx Server Error

Semua setelan mundur eksponensial di library klien Ruby dapat dikonfigurasi. Secara default, operasi melalui library klien Ruby menggunakan setelan berikut untuk penundaan eksponensial:

Setelan Nilai default
Percobaan ulang otomatis Benar
Jumlah maksimum percobaan ulang 3
Waktu tunggu awal 1 detik
Pengganda waktu tunggu per iterasi 2
Jumlah waktu tunggu maksimum 60 detik
Batas waktu default 900 detik

Ada sebagian operasi Ruby yang idempoten bersyarat (aman untuk dicoba ulang dalam kondisi tertentu) saat menyertakan argumen tertentu:

  • if_generation_match atau generation

    • Aman untuk dicoba ulang jika parameter generation atau if_generation_match diteruskan sebagai argumen ke metode. Sering kali metode hanya menerima salah satu dari dua parameter ini.
  • if_metageneration_match

    • Aman untuk dicoba ulang jika parameter if_metageneration_match diteruskan sebagai opsi.

Secara default, semua operasi idempoten dicoba ulang, dan operasi idempoten bersyarat dicoba ulang hanya jika kasus kondisi telah terpenuhi. Operasi non-idempoten tidak akan dicoba ulang. Lihat Menyesuaikan percobaan ulang untuk mengetahui contoh cara mengubah perilaku percobaan ulang default.

REST API

Saat memanggil JSON atau XML API secara langsung, Anda harus menggunakan algoritma backoff eksponensial untuk mengimplementasikan strategi percobaan ulang Anda sendiri.

Menyesuaikan percobaan ulang

Konsol

Anda tidak dapat menyesuaikan perilaku percobaan ulang menggunakan konsol Google Cloud .

Command line

Untuk perintah gcloud storage, Anda dapat mengontrol strategi percobaan ulang dengan membuat konfigurasi bernama dan menetapkan beberapa atau semua properti berikut ini:

Setelan Nilai default (dalam detik)
base_retry_delay 1
exponential_sleep_multiplier 2
max_retries 32
max_retry_delay 32

Anda kemudian menerapkan konfigurasi yang ditentukan per perintah menggunakan flag --configuration di seluruh project atau untuk semua perintah Google Cloud CLI menggunakan perintah gcloud config set.

Library klien

C++

Untuk menyesuaikan perilaku percobaan ulang, berikan nilai untuk opsi berikut saat Anda melakukan inisialisasi objek google::cloud::storage::Client:

  • google::cloud::storage::RetryPolicyOption: Library ini menyediakan kelas google::cloud::storage::LimitedErrorCountRetryPolicy dan google::cloud::storage::LimitedTimeRetryPolicy. Anda dapat menyediakan kelas Anda sendiri, yang harus mengimplementasikan antarmuka google::cloud::RetryPolicy.

  • google::cloud::storage::BackoffPolicyOption: Library ini menyediakan kelas google::cloud::storage::ExponentialBackoffPolicy. Anda dapat menyediakan kelas Anda sendiri, yang harus mengimplementasikan antarmuka google::cloud::storage::BackoffPolicy.

  • google::cloud::storage::IdempotencyPolicyOption: Library ini menyediakan kelas google::cloud::storage::StrictIdempotencyPolicy dan google::cloud::storage::AlwaysRetryIdempotencyPolicy. Anda dapat menyediakan kelas Anda sendiri, yang harus mengimplementasikan antarmuka google::cloud::storage::IdempotencyPolicy.

Untuk mengetahui informasi selengkapnya, lihat dokumentasi referensi library klien 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#

Anda tidak dapat menyesuaikan strategi percobaan ulang default yang digunakan oleh library klien C#.

Go

Saat Anda melakukan inisialisasi klien penyimpanan, konfigurasi percobaan ulang default akan ditetapkan. Kecuali jika diabaikan, opsi dalam konfigurasi tersebut akan ditetapkan ke nilai default. Pengguna dapat mengonfigurasi perilaku percobaan ulang non-default untuk satu panggilan library (menggunakan BucketHandle.Retryer dan ObjectHandle.Retryer) atau untuk semua panggilan yang dilakukan oleh klien (menggunakan Client.SetRetry). Untuk mengubah perilaku coba lagi, teruskan RetryOptions yang relevan ke salah satu metode ini.

Lihat contoh kode berikut untuk mempelajari cara menyesuaikan perilaku percobaan ulang.

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

Saat Anda menginisialisasi Storage, instance RetrySettings juga diinisialisasi. Kecuali jika diabaikan, opsi di RetrySettings akan ditetapkan ke nilai default. Untuk mengubah perilaku percobaan ulang otomatis default, teruskan StorageRetryStrategy kustom ke StorageOptions yang digunakan untuk membuat instance Storage. Untuk memodifikasi salah satu parameter skalar lainnya, teruskan RetrySettings kustom ke StorageOptions yang digunakan untuk membuat instance Storage.

Lihat contoh berikut untuk mempelajari cara menyesuaikan perilaku percobaan ulang:


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

Saat Anda menginisialisasi Cloud Storage, file konfigurasi retryOptions juga akan diinisialisasi. Kecuali jika diabaikan, opsi dalam konfigurasi tersebut akan ditetapkan ke nilai default. Untuk mengubah perilaku percobaan ulang default, teruskan konfigurasi percobaan ulang kustom retryOptions ke dalam konstruktor penyimpanan saat inisialisasi. Library klien Node.js dapat otomatis menggunakan strategi backoff untuk mencoba ulang permintaan dengan parameter autoRetry.

Lihat contoh kode berikut untuk mempelajari cara menyesuaikan perilaku percobaan ulang.

/**
 * 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

Anda tidak dapat menyesuaikan strategi percobaan ulang default yang digunakan oleh library klien PHP.

Python

Untuk mengubah perilaku coba ulang default, buat salinan objek google.cloud.storage.retry.DEFAULT_RETRY dengan memanggilnya menggunakan metode with_XXX. Library klien Python otomatis menggunakan strategi backoff untuk mencoba ulang permintaan jika Anda menyertakan parameter DEFAULT_RETRY.

Perhatikan bahwa with_predicate tidak didukung untuk operasi yang mengambil atau mengirim data payload ke objek, seperti upload dan download. Sebaiknya Anda mengubah atribut satu per satu. Untuk mengetahui informasi selengkapnya, lihat Referensi Percobaan Ulang google-api-core.

Untuk mengonfigurasi coba lagi bersyarat Anda sendiri, buat objek ConditionalRetryPolicy dan gabungkan objek Retry kustom Anda dengan DEFAULT_RETRY_IF_GENERATION_SPECIFIED, DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED, atau DEFAULT_RETRY_IF_ETAG_IN_JSON.

Lihat contoh kode berikut untuk mempelajari cara menyesuaikan perilaku percobaan ulang.

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

Saat Anda melakukan inisialisasi klien penyimpanan, semua konfigurasi percobaan ulang akan ditetapkan ke nilai yang ditampilkan pada tabel di atas. Untuk mengubah perilaku percobaan ulang default, teruskan konfigurasi percobaan ulang saat melakukan inisialisasi klien penyimpanan.

Untuk mengganti jumlah percobaan ulang untuk operasi tertentu, teruskan retries dalam parameter options operasi.

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

Gunakan algotitma backoff eksponensial untuk mengimplementasikan strategi percobaan ulang Anda sendiri.

Algotitma backoff eksponensial

Algotitma backoff eksponensial mencoba ulang permintaan menggunakan waktu tunggu yang meningkat secara eksponensial di antara permintaan, hingga waktu backoff maksimum. Biasanya Anda harus menggunakan backoff eksponensial dengan jitter untuk mencoba ulang permintaan yang memenuhi kriteria respons dan idempotensi. Untuk praktik terbaik dalam mengimplementasikan percobaan ulang otomatis dengan backoff eksponensial, lihat Mengatasi Kegagalan Beruntun.

Antipola percobaan ulang

Sebaiknya gunakan atau sesuaikan mekanisme coba lagi bawaan jika berlaku; lihat menyesuaikan percobaan ulang. Baik Anda menggunakan mekanisme coba lagi default, menyesuaikannya, atau menerapkan logika coba lagi Anda sendiri, Anda harus menghindari anti-pola umum berikut karena dapat memperburuk masalah, bukan menyelesaikannya.

Mencoba lagi tanpa backoff

Mencoba ulang permintaan secara langsung atau dengan penundaan yang sangat singkat dapat menyebabkan kegagalan beruntun, yaitu kegagalan yang dapat memicu kegagalan lainnya.

Cara menghindarinya: Terapkan backoff eksponensial dengan jitter. Strategi ini secara progresif meningkatkan waktu tunggu di antara percobaan ulang dan menambahkan elemen acak untuk mencegah percobaan ulang membebani layanan secara berlebihan.

Mencoba ulang operasi non-idempoten tanpa syarat

Menjalankan operasi yang tidak bersifat idempoten secara berulang dapat menyebabkan efek samping yang tidak diinginkan, seperti penimpaan atau penghapusan data yang tidak diinginkan.

Cara menghindarinya: Pahami secara menyeluruh karakteristik keidempotenan setiap operasi seperti yang dijelaskan di bagian keidempotenan operasi. Untuk operasi non-idempoten, pastikan logika percobaan ulang Anda dapat menangani potensi duplikat atau menghindari percobaan ulang sama sekali. Berhati-hatilah dengan percobaan ulang yang dapat menyebabkan kondisi persaingan.

Mencoba lagi error yang tidak dapat dicoba lagi

Memperlakukan semua error sebagai dapat dicoba lagi dapat menimbulkan masalah. Beberapa error, misalnya, kegagalan otorisasi atau permintaan tidak valid, bersifat persisten dan mencoba ulang tanpa mengatasi penyebab yang mendasarinya tidak akan berhasil dan dapat mengakibatkan aplikasi terjebak dalam loop tak terbatas.

Cara menghindarinya: Kategorikan error menjadi sementara (dapat dicoba lagi) dan permanen (tidak dapat dicoba lagi). Coba lagi hanya error sementara seperti kode HTTP 408, 429, dan 5xx, atau masalah koneksi tertentu. Untuk error permanen, catat error tersebut dan tangani penyebab yang mendasarinya dengan tepat.

Mengabaikan batas percobaan ulang

Mencoba lagi tanpa batas dapat menyebabkan kehabisan resource di aplikasi Anda atau terus mengirim permintaan ke layanan yang tidak akan pulih tanpa intervensi.

Cara menghindarinya: Sesuaikan batas percobaan ulang dengan sifat workload Anda. Untuk beban kerja yang sensitif terhadap latensi, pertimbangkan untuk menetapkan durasi total percobaan ulang maksimum untuk memastikan respons atau kegagalan tepat waktu. Untuk beban kerja batch, yang mungkin mentoleransi periode percobaan ulang yang lebih lama untuk error sisi server sementara, pertimbangkan untuk menetapkan batas total percobaan ulang yang lebih tinggi.

Mencoba ulang secara berlebihan

Menambahkan logika percobaan ulang tingkat aplikasi kustom di atas mekanisme percobaan ulang yang ada dapat menyebabkan jumlah upaya percobaan ulang yang berlebihan. Misalnya, jika aplikasi Anda mencoba lagi operasi tiga kali, dan library klien yang mendasarinya juga mencoba lagi tiga kali untuk setiap upaya aplikasi Anda, Anda dapat berakhir dengan sembilan upaya percobaan lagi. Mengirimkan percobaan ulang dalam jumlah besar untuk error yang tidak dapat dicoba ulang dapat menyebabkan pembatasan permintaan, sehingga membatasi throughput semua beban kerja. Jumlah percobaan ulang yang tinggi juga dapat meningkatkan latensi permintaan tanpa meningkatkan tingkat keberhasilan.

Cara menghindarinya: Sebaiknya gunakan dan konfigurasi mekanisme coba lagi bawaan. Jika Anda harus menerapkan percobaan ulang tingkat aplikasi, seperti untuk logika bisnis tertentu yang mencakup beberapa operasi, lakukan dengan pemahaman yang jelas tentang perilaku percobaan ulang yang mendasarinya. Pertimbangkan untuk menonaktifkan atau membatasi percobaan ulang secara signifikan di salah satu lapisan untuk mencegah efek multiplikatif.

Langkah berikutnya