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 coba lagi ini dikonfigurasi per RPC. Layanan dapat memilih untuk hanya mengaktifkan percobaan ulang untuk sebagian kecil RPC. Setiap RPC untuk layanan dapat dikonfigurasi secara berbeda.

Coba ulang parameter

Library klien memiliki dua jenis parameter percobaan ulang yang dapat dikonfigurasi:

  1. Kode Status Coba Lagi: Kumpulan kode status untuk dicoba lagi.
  2. Waktu Tunggu Coba Lagi atau Batas Percobaan: RetrySettings yang dapat dikonfigurasi untuk menentukan batas.

Lokasi konfigurasi Coba Ulang RPC default

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

  • Kode Status Coba Lagi: 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 Coba Lagi: 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

Dengan mengaktifkan percobaan ulang, RPC dapat mencoba beberapa kali untuk melakukan panggilan yang berhasil. Panggilan yang berhasil adalah respons dari server yang menampilkan Kode Status OK (dari gRPC) atau Kode Status 2xx (dari HttpJson).

Percobaan 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 Individu (upaya) dikontrol oleh setelan berikut:

Batas Total RPC (operasi) dikontrol oleh setelan berikut:

Saat RPC dicoba lagi

RPC akan dicoba lagi 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 melampaui batas RPC individual, tetapi masih berada dalam batas total RPC.

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

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

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

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 tunda berikut:

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

Jitter

Jitter adalah varians 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 percobaan, 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 menyebabkan waktu tunda berikut:

  • Percobaan 1: Menunda nilai acak antara [1, 100] md
  • Percobaan 2: Menunda nilai acak antara [1, 200] md
  • Percobaan 3: Menunda nilai acak antara [1, 400] md
  • Percobaan 4: Menunda nilai acak antara [1, 500] md
  • ...
  • Percobaan 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 yang dilakukan:

Nomor Percobaan Waktu Tunggu RPC Penundaan Percobaan Kembali Panggilan Diaktifkan Panggilan Diakhiri
1 5.000 md 0 md 0 md 5.000 md

Contoh coba lagi

Contoh ini memungkinkan 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 yang dilakukan:

Nomor Percobaan Waktu Tunggu RPC Penundaan Percobaan Kembali Panggilan Diaktifkan Panggilan Diakhiri
1 1.500 md 0 md 0 md 1.500 md
2 (Coba lagi) 3000 md 200 md 1.700 md 4.700 md
3 (Percobaan Ulang Tidak Dilakukan) - 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 menunjukkan 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 yang dilakukan:

Nomor Percobaan Waktu Tunggu RPC Penundaan Percobaan Kembali Panggilan Diaktifkan Panggilan Diakhiri
1 1.500 md 0 md 0 md 1.500 md
2 (Coba lagi) 3000 md 200 md 1.700 md 4.700 md
3 (Coba lagi) 4900 md 400 md 5100 md 10.000 md

Nilai Waktu Tunggu RPC percobaan ulang ketiga dibatasi karena nilai Total Waktu Tunggu. Menggunakan pengganda (2.0) dengan nilai waktu tunggu sebelumnya (3000 md) akan menghasilkan Waktu Tunggu RPC 6000 md. Namun, Waktu Tunggu RPC tidak boleh melebihi Waktu Tunggu Total dan dikurangi menjadi "waktu yang 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 yang dilakukan:

Nomor Percobaan Waktu Tunggu RPC Penundaan Percobaan Kembali Panggilan Diaktifkan Panggilan Diakhiri
1 500 md 0 md 0 md 500 md
2 (Coba lagi) 1000 md 200 md 700 md 1.700 md
3 (Coba lagi) 1900 md 400 md 2100 md 4.000 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 sedang menyetel konfigurasi percobaan ulang kustom untuk RPC ExportAssets AssetServiceClient. Kode ini mengonfigurasi RPC ExportAssets 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: java AssetServiceSettings assetSettings = AssetServiceSettings.create(assetStubSettingsBuilder.build()); 4.Buat klien dengan setelan sebagai assetClient. java 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 coba lagi klien.

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

Kecuali jika Anda secara eksplisit menentukan jumlah upaya maksimal (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 menyulitkan untuk memprediksi kapan permintaan benar-benar dikirim.

RPC menampilkan kegagalan sebelum nilai Total Waktu Tunggu tercapai.

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

Saya mengonfigurasi setelan kustom dan mengalami masalah kuota.

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

Pertimbangkan untuk meningkatkan penundaan percobaan ulang (penundaan percobaan ulang awal dan pengganda percobaan ulang) agar upaya percobaan ulang dilakukan dengan jeda dan lebih jarang. Perhatikan bahwa hal ini dapat menyebabkan respons yang lebih lambat.

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