Mengonfigurasi percobaan ulang sisi klien

Library Klien Cloud untuk Java menggunakan percobaan ulang untuk menangani kegagalan sementara yang tidak terduga (yaitu, server tidak tersedia untuk sementara). Beberapa upaya dapat menghasilkan respons yang berhasil dari server.

Nilai percobaan ulang default dipilih oleh tim yang mengoperasikan layanan cloud. Nilai percobaan ulang ini dikonfigurasi per RPC. Layanan dapat memilih untuk hanya mengaktifkan percobaan ulang untuk sebagian RPC. Setiap RPC untuk layanan dapat dikonfigurasi secara berbeda.

Parameter percobaan ulang

Library klien memiliki dua jenis parameter percobaan ulang untuk dikonfigurasi:

  1. Kode Status Percobaan Ulang: Kumpulan kode status untuk dicoba ulang.
  2. Waktu Tunggu Percobaan Ulang atau Batas Upaya: RetrySettings yang dapat dikonfigurasi RetrySettings

Lokasi konfigurasi Percobaan Ulang RPC default

Konfigurasi percobaan ulang default ditentukan dalam file {Client}StubSettings yang dibuat. Dengan menggunakan ExportAssets RPC di Java-Asset v3.64.0 sebagai contoh, konfigurasi percobaan ulang default ditentukan di tempat berikut:

  • Kode Status Percobaan Ulang: dikonfigurasi dalam file AssetServiceStubSettings.java. Contoh:

    ImmutableMap.Builder<String, ImmutableSet<StatusCode.Code>> definitions = ImmutableMap.builder();
    definitions.put("no_retry_0_codes", ImmutableSet.copyOf(Lists.<StatusCode.Code>newArrayList()));
    // ... More StatusCode configurations
    RETRYABLE_CODE_DEFINITIONS = definitions.build();
    
  • Parameter Percobaan Ulang: Dikonfigurasi dalam file AssetServiceStubSettings.java. Contoh:

    ImmutableMap.Builder<String, RetrySettings> definitions = ImmutableMap.builder();
    RetrySettings settings = null;
    settings =
        RetrySettings.newBuilder()
        .setInitialRpcTimeoutDuration(Duration.ofMillis(60000L))
        .setRpcTimeoutMultiplier(1.0)
        .setMaxRpcTimeoutDuration(Duration.ofMillis(60000L))
        .setTotalTimeoutDuration(Duration.ofMillis(60000L))
        .build();
    definitions.put("no_retry_0_params", settings);
    // ... More RetrySettings configurations
    RETRY_PARAM_DEFINITIONS = definitions.build();
    

Kedua konfigurasi dipetakan ke RPC dalam file AssetServiceStubSettings.java. Contoh:

builder
  .exportAssetsSettings()
  .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("no_retry_0_codes"))
  .setRetrySettings(RETRY_PARAM_DEFINITIONS.get("no_retry_0_params"));

Konsep percobaan ulang library klien

Mengaktifkan percobaan ulang memungkinkan RPC melakukan beberapa upaya untuk mencoba dan mencapai panggilan yang berhasil. Panggilan yang berhasil adalah respons dari server yang menampilkan Kode Status OK (dari gRPC) atau Kode Status 2xx (dari HttpJson).

Upaya versus operasi

Konfigurasi RetrySettings berikut mengubah setelan percobaan ulang untuk upaya dan operasi RPC:

settings =
  RetrySettings.newBuilder()
      .setInitialRetryDelayDuration(Duration.ofMillis(100L))
      .setRetryDelayMultiplier(1.3)
      .setMaxRetryDelayDuration(Duration.ofMillis(60000L))
      .setInitialRpcTimeoutDuration(Duration.ofMillis(60000L))
      .setRpcTimeoutMultiplier(1.0)
      .setMaxRpcTimeoutDuration(Duration.ofMillis(60000L))
      .setTotalTimeoutDuration(Duration.ofMillis(60000L))
      .build();

Upaya RPC adalah upaya individual yang dilakukan dan operasi RPC adalah kumpulan semua upaya yang dilakukan. Satu pemanggilan RPC akan memiliki satu atau beberapa upaya dalam satu operasi.

Batas RPC Individual (upaya) dikontrol oleh setelan berikut:

Batas RPC Total (operasi) dikontrol oleh setelan berikut:

Saat RPC dicoba ulang

RPC akan dicoba ulang jika kedua skenario berikut terjadi:

  • Kode status yang tidak berhasil diterima oleh library dan kode status ditandai bahwa kode tersebut dapat dicoba lagi.
  • Pemanggilan RPC melebihi batas RPC individual, tetapi masih berada dalam batas RPC total.

Jika hanya satu skenario yang benar, atau jika tidak ada skenario yang benar, RPC tidak akan dicoba ulang.

Misalnya, jika total waktu tunggu belum terlampaui, tetapi upaya terbaru menerima kode status yang tidak dapat dicoba ulang.

Selain itu, saat mengonfigurasi batas RPC, Anda dapat mengonfigurasi batas untuk setiap upaya serta batas RPC total. Algoritma percobaan ulang akan memastikan bahwa batas upaya individual berada dalam batas RPC total.

Backoff eksponensial

Backoff eksponensial akan mencoba ulang permintaan dengan penundaan yang meningkat di antara setiap upaya percobaan ulang. Nilai penundaan percobaan ulang ini dapat dibatasi dengan nilai penundaan percobaan ulang maksimum.

Misalnya, konfigurasi percobaan ulang berikut dapat menghasilkan waktu penundaan berikut:

Initial Retry Delay: 100ms
Retry Delay Multiplier: 2.0
Max Retry Delay: 500ms
  • Upaya 1: Penundaan 100 md
  • Upaya 2: Penundaan 200 md
  • Upaya 3: Penundaan 400 md
  • Upaya 4: Penundaan 500 md
  • ...
  • Upaya X: Penundaan 500 md

Jitter

Jitter adalah varian tambahan yang menggunakan keacakan untuk menyebarkan waktu pemanggilan RPC. Google Cloud Library Klien selalu mengaktifkan jitter untuk percobaan ulang. Hal ini membantu menyebarkan upaya percobaan ulang tanpa membebani server.

Nilai acak jitter dihitung berdasarkan penundaan percobaan ulang. Sebelum setiap upaya, algoritma percobaan ulang akan menghitung nilai acak antara [1, RETRY_DELAY]. Nilai yang dihitung ini adalah perkiraan penundaan sebelum permintaan dikirim ke server.

Konfigurasi percobaan ulang berikut menggunakan jitter dan backoff eksponensial.

Initial Retry Delay: 100ms
Retry Delay Multiplier: 2.0
Max Retry Delay: 500ms

Hal ini dapat menghasilkan waktu penundaan berikut:

  • Upaya 1: Menunda nilai acak antara [1, 100] md
  • Upaya 2: Menunda nilai acak antara [1, 200] md
  • Upaya 3: Menunda nilai acak antara [1, 400] md
  • Upaya 4: Menunda nilai acak antara [1, 500] md
  • ...
  • Upaya X: Menunda nilai acak antara [1, 500] md

Contoh percobaan ulang

Contoh berikut menunjukkan perilaku beberapa konfigurasi percobaan ulang.

Tidak ada percobaan ulang

Contoh ini menonaktifkan percobaan ulang.

RetrySettings defaultNoRetrySettings =
    RetrySettings.newBuilder()
    // Use the default configurations for other settings
    .setTotalTimeoutDuration(Duration.ofMillis(5000L))
    // Explicitly set retries as disabled (maxAttempts == 1)
    .setMaxAttempts(1)
    .build();

Atau, perilaku ini dapat dikonfigurasi dengan contoh ini:

RetrySettings defaultNoRetrySettings =
    RetrySettings.newBuilder()
    .setLogicalTimeoutDuration(Duration.ofMillis(5000L))
    .build();

Tabel berikut menunjukkan upaya:

Nomor Upaya Waktu Tunggu RPC Penundaan Percobaan Ulang Panggilan Diaktifkan Panggilan Berakhir
1 5000 md 0 md 0 md 5000 md

Contoh percobaan ulang

Contoh ini mengaktifkan percobaan ulang dengan penundaan dan waktu tunggu yang ditentukan.

RetrySettings.newBuilder()
    .setInitialRetryDelayDuration(Duration.ofMillis(200L))
    .setRetryDelayMultiplier(2.0)
    .setMaxRetryDelayDuration(Duration.ofMillis(500L))
    .setInitialRpcTimeoutDuration(Duration.ofMillis(1500L))
    .setRpcTimeoutMultiplier(2.0)
    .setMaxRpcTimeoutDuration(Duration.ofMillis(3000L))
    .setTotalTimeoutDuration(Duration.ofMillis(5000L))
    .build();

Tabel berikut menunjukkan upaya:

Nomor Upaya Waktu Tunggu RPC Penundaan Percobaan Ulang Panggilan Diaktifkan Panggilan Berakhir
1 1500 md 0 md 0 md 1500 md
2 (Percobaan Ulang) 3000 md 200 md 1700 md 4700 md
3 (Percobaan Ulang Tidak Dicoba) - 400 md - -

Contoh percobaan ulang: total waktu tunggu yang lebih lama

Contoh ini mirip dengan contoh percobaan ulang pertama, tetapi memiliki total waktu tunggu yang lebih lama untuk menampilkan upaya percobaan ulang tambahan dan Waktu Tunggu RPC yang dibatasi untuk upaya percobaan ulang terakhir.

RetrySettings.newBuilder()
    .setInitialRetryDelayDuration(Duration.ofMillis(200L))
    .setRetryDelayMultiplier(2.0)
    .setMaxRetryDelayDuration(Duration.ofMillis(500L))
    .setInitialRpcTimeoutDuration(Duration.ofMillis(1500L))
    .setRpcTimeoutMultiplier(2.0)
    .setMaxRpcTimeoutDuration(Duration.ofMillis(3000L))
    .setTotalTimeoutDuration(Duration.ofMillis(10000L))
    .build();

Tabel berikut menunjukkan upaya:

Nomor Upaya Waktu Tunggu RPC Penundaan Percobaan Ulang Panggilan Diaktifkan Panggilan Berakhir
1 1500 md 0 md 0 md 1500 md
2 (Percobaan Ulang) 3000 md 200 md 1700 md 4700 md
3 (Percobaan Ulang) 4900 md 400 md 5100 md 10000 md

Nilai Waktu Tunggu RPC percobaan ulang ketiga dibatasi karena nilai Total Waktu Tunggu. Menggunakan pengali (2.0) dengan nilai waktu tunggu sebelumnya (3000 md) akan menghasilkan Waktu Tunggu RPC sebesar 6000 md. Namun, Waktu Tunggu RPC tidak boleh melebihi Total Waktu Tunggu dan dikurangi menjadi "waktu tersisa" (10000 - 5100 = 4900).

Contoh percobaan ulang: waktu tunggu RPC yang dibatasi

RetrySettings defaultRetrySettings =
    RetrySettings.newBuilder()
        .setInitialRetryDelayDuration(Duration.ofMillis(200L))
        .setRetryDelayMultiplier(2.0)
        .setMaxRetryDelayDuration(Duration.ofMillis(500L))
        .setInitialRpcTimeoutDuration(Duration.ofMillis(500L))
        .setRpcTimeoutMultiplier(2.0)
        .setMaxRpcTimeoutDuration(Duration.ofMillis(2000L))
        .setTotalTimeoutDuration(Duration.ofMillis(4000L))
        .build();

Tabel berikut menunjukkan upaya:

Nomor Upaya Waktu Tunggu RPC Penundaan Percobaan Ulang Panggilan Diaktifkan Panggilan Berakhir
1 500 md 0 md 0 md 500 md
2 (Percobaan Ulang) 1000 md 200 md 700 md 1700 md
3 (Percobaan Ulang) 1900 md 400 md 2100 md 4000 md

Contoh lain saat Waktu Tunggu RPC dibatasi agar tidak melebihi total waktu tunggu.

Cara mengonfigurasi parameter percobaan ulang kustom untuk RPC

Contoh berikut menggunakan library klien Java-Asset:

  1. Buat class RetrySettings dengan konfigurasi kustom Anda:

    RetrySettings customRetrySettings =
      RetrySettings.newBuilder()
        // ... Retry Configurations
        .build();
    RetrySettings customRetrySettings2 =
      RetrySettings.newBuilder()
        // ... Retry Configurations
        .build();
    
  2. Buat StubSettings.Builder untuk klien Anda dan konfigurasikan untuk RPC:

    AssetServiceStubSettings.Builder assetStubSettingsBuilder = AssetServiceStubSettings.newBuilder();
    assetStubSettingsBuilder
      .exportAssetsSettings()
      // Set your custom Retry Settings
      .setRetrySettings(customRetrySettings)
      // Set your custom Retryable Codes
      .setRetryableCodes(ImmutableSet.of(StatusCode.Code.DEADLINE_EXCEEDED));
    

    Cuplikan kode yang diberikan menetapkan konfigurasi percobaan ulang kustom untuk ExportAssets RPC AssetServiceClient. Kode ini mengonfigurasi ExportAssets RPC untuk menggunakan setelan percobaan ulang yang dikonfigurasi di customRetrySettings dan menetapkan kode yang dapat dicoba ulang menjadi DEADLINE_EXCEEDED.

  3. Buat setelan untuk klien sebagai assetSettings:

    AssetServiceSettings assetSettings = AssetServiceSettings.create(assetStubSettingsBuilder.build());
    
  4. Buat klien dengan setelan sebagai assetClient.

    try (AssetServiceClient assetClient = AssetServiceClient.create(assetSettings)) {
      ...
    }
    

Ulangi langkah 2 untuk setiap RPC yang ingin Anda konfigurasi. Contoh:

AssetServiceStubSettings.Builder assetStubSettingsBuilder = AssetServiceStubSettings.newBuilder();
  
// Modify the retry params for ExportAssets RPC
assetStubSettingsBuilder
  .exportAssetsSettings()
  .setRetrySettings(customRetrySettings)
  .setRetryableCodes(ImmutableSet.of(StatusCode.Code.DEADLINE_EXCEEDED));

// Modify the retry params for ListAssets RPC
assetStubSettingsBuilder
  .listAssetsSettings()
  .setRetrySettings(customRetrySettings2)
  .setRetryableCodes(ImmutableSet.of(StatusCode.Code.UNAVAILABLE));

FAQ

Berikut adalah pertanyaan umum terkait perilaku percobaan ulang klien.

Saya mengharapkan X upaya percobaan ulang, tetapi upaya tersebut dilakukan Y kali.

Kecuali jika Anda secara eksplisit menentukan jumlah upaya maksimum (bersama dengan menonaktifkan konfigurasi waktu tunggu), Anda mungkin tidak akan melihat jumlah upaya percobaan ulang yang sama secara konsisten. Nilai acak jitter untuk penundaan RPC membuat sulit untuk memprediksi kapan permintaan sebenarnya dikirim.

RPC menampilkan kegagalan sebelum nilai Total Waktu Tunggu tercapai.

Algoritma percobaan ulang akan menghitung nilai penundaan percobaan ulang yang di-jitter selama setiap upaya percobaan ulang. Penundaan percobaan ulang yang dihitung akan dijadwalkan untuk dijalankan di masa mendatang (yaitu, currentTime() + jitteredRetryDelay). Jika waktu upaya yang dijadwalkan melebihi total waktu tunggu, upaya percobaan ulang terakhir tidak akan dilakukan.

Saya mengonfigurasi setelan kustom dan mengalami masalah kuota.

Anda mungkin telah mengonfigurasi RetrySettings untuk berjalan terlalu agresif. Nilai percobaan ulang default dipilih oleh tim yang mengoperasikan layanan.

Pertimbangkan untuk meningkatkan penundaan percobaan ulang (penundaan percobaan ulang awal dan pengali percobaan ulang) sehingga upaya percobaan ulang diberi jarak dan lebih jarang. Perhatikan bahwa hal ini dapat menyebabkan respons yang lebih lambat.

Kasus penggunaan Anda mungkin memerlukan respons yang lebih cepat atau upaya percobaan ulang yang lebih sering, atau keduanya. Jika demikian, coba tingkatkan batas kuota.