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:
- Retry Status Code: Es el conjunto de códigos de estado para reintentar.
- 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:
setInitialRetryDelayDuration: Es la demora antes del primer intento.setRetryDelayMultiplier: Es el multiplicador de demora que se aplica entre cada intento.setMaxRetryDelayDuration: Es la demora máxima posible para un intento.setInitialRpcTimeoutDuration: Es el tiempo de espera para el primer intento.setRpcTimeoutMultiplier: Es el multiplicador de tiempo de espera que se aplica entre cada intento.setMaxRpcTimeoutDuration: Es el tiempo de espera máximo posible para un intento.
Los límites totales de RPC (una operación) se controlan con los siguientes parámetros de configuración:
setTotalTimeoutDuration: Tiempo de espera total permitido para toda la operación.setMaxAttempts: Es la cantidad máxima de intentos permitidos.
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
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
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(