Configura reintentos del cliente

Las bibliotecas cliente de Cloud para Java usan reintentos para controlar errores transitorios inesperados (es decir, el servidor no está disponible temporalmente). Varios intentos pueden generar una respuesta exitosa del servidor.

El equipo que opera el servicio en la nube selecciona los valores de reintento predeterminados. Estos valores de reintento se configuran por RPC. Un servicio puede optar por habilitar solo los reintentos para un subconjunto de RPCs. Es posible que cada RPC de un servicio esté configurada de manera diferente.

Parámetros de reintento

Las bibliotecas cliente tienen dos tipos de parámetros de reintento para configurar:

  1. Retry Status Code: Es el conjunto de códigos de estado para reintentar.
  2. Tiempo de espera para reintentar o límites de intentos: RetrySettings configurables para definir los límites.

Ubicación predeterminada de la configuración de reintentos de RPC

Las configuraciones de reintento predeterminadas se definen en el archivo {Client}StubSettings generado. Si se usa la RPC de ExportAssets en Java-Asset v3.64.0 como ejemplo, las configuraciones predeterminadas de reintentos se definen en los siguientes lugares:

  • Códigos de estado de reintento: Se configuran en el archivo AssetServiceStubSettings.java. Ejemplo:

    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();
    
  • Parámetros de reintento: Se configuran en el archivo AssetServiceStubSettings.java. Ejemplo:

    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();
    

Ambas configuraciones se asignan a la RPC en el archivo AssetServiceStubSettings.java. Ejemplo:

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

Conceptos de reintentos de la biblioteca cliente

Habilitar los reintentos permite que una RPC intente varias veces lograr una llamada exitosa. Una llamada exitosa es una respuesta de un servidor que devuelve un código de estado OK (de gRPC) o un código de estado 2xx (de HttpJson).

Intento en comparación con operación

La siguiente configuración de RetrySettings modifica la configuración de reintentos para el intento y la operación de una 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();

Un intento de RPC es el intento individual que se realiza, y una operación de RPC es una colección de todos los intentos realizados. Una sola invocación de RPC tendrá uno o más intentos en una sola operación.

Los límites de RPC individuales (un intento) se controlan con los siguientes parámetros de configuración:

Los límites totales de RPC (una operación) se controlan con los siguientes parámetros de configuración:

Cuándo se reintenta una RPC

Se volverá a intentar una RPC cuando ocurran las siguientes situaciones:

  • La biblioteca recibe un código de estado que no es correcto y se marca que se puede volver a intentar.
  • Una invocación de RPC supera los límites individuales de RPC, pero aún se encuentra dentro de los límites totales de RPC.

Si solo un caso es verdadero o si ninguno lo es, no se volverá a intentar la RPC.

Por ejemplo, si no se superó el tiempo de espera total, pero el intento más reciente recibe un código de estado que no se puede reintentar.

Además, cuando configures los límites de RPC, puedes configurar los límites para cada intento, así como los límites totales de RPC. El algoritmo de reintento garantizará que los límites de un intento individual se encuentren dentro de los límites totales de la RPC.

Retirada exponencial

La retirada exponencial volverá a intentar las solicitudes con un retraso cada vez mayor entre cada reintento. Este valor de demora de reintento se puede limitar con un valor máximo de demora de reintento.

Por ejemplo, las siguientes configuraciones de reintento pueden generar los siguientes tiempos de demora:

Initial Retry Delay: 100ms
Retry Delay Multiplier: 2.0
Max Retry Delay: 500ms
  • Intento 1: Retraso de 100 ms
  • Intento 2: Retraso de 200 ms
  • Intento 3: Retraso de 400 ms
  • Intento 4: Retraso de 500 ms
  • Intento X: Retraso de 500 ms
Establece un límite para las operaciones de RPC configurando el valor de TotalTimeout o MaxAttempts.

Jitter

La fluctuación es una varianza agregada que usa la aleatoriedad para distribuir el momento en que se invocan las RPC. Google Cloud Las bibliotecas cliente siempre habilitan la fluctuación para los reintentos. Esto ayuda a distribuir los intentos de reintento sin sobrecargar el servidor.

El valor aleatorio de fluctuación se calcula en función de la demora en el reintento. Antes de cada intento, el algoritmo de reintentos calculará un valor aleatorio entre [1, RETRY_DELAY]. Este valor calculado es la demora aproximada antes de que se envíe la solicitud al servidor.

Las siguientes configuraciones de reintento utilizan jitter y retirada exponencial.

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

Esto podría generar los siguientes tiempos de demora:

  • Intento 1: Retrasa un valor aleatorio entre [1, 100] ms
  • Intento 2: Retrasa un valor aleatorio entre [1, 200] ms
  • Intento 3: Demora un valor aleatorio entre [1, 400] ms
  • Intento 4: Demora un valor aleatorio entre [1, 500] ms
  • Intento X: Retrasa un valor aleatorio entre [1, 500] ms
Establece un límite para las operaciones de RPC configurando el valor de TotalTimeout o MaxAttempts.

Ejemplos de reintentos

En los siguientes ejemplos, se muestra el comportamiento de algunas configuraciones de reintentos.

No se reintenta

En este ejemplo, se inhabilitan los reintentos.

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();

Como alternativa, este comportamiento se puede configurar con este ejemplo:

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

En la siguiente tabla, se muestran los intentos:

Número de intento Tiempo de espera de RPC Retraso de las repeticiones de intento Llamada invocada Llamada finalizada
1 5000 ms 0 ms 0 ms 5000 ms

Ejemplo de reintento

En este ejemplo, se habilitan los reintentos con los tiempos de espera y los retrasos especificados.

RetrySettings.newBuilder()
    .setInitialRetryDelayDuration(Duration.ofMillis(200L))
    .setRetryDelayMultiplier(2.0)
    .setMaxRetryDelayDuration(Duration.ofMillis(500L))
    .setInitialRpcTimeoutDuration(