En esta página se describe cómo vuelven a intentar las herramientas de Cloud Storage las solicitudes fallidas y cómo personalizar el comportamiento de los reintentos. También se describen las consideraciones para volver a intentar las solicitudes.
Información general
Hay dos factores que determinan si una solicitud se puede volver a intentar de forma segura:
La respuesta que recibes de la solicitud.
La idempotencia de la solicitud.
Respuesta
La respuesta que recibas de tu solicitud indica si es útil o no volver a intentarlo. Las respuestas relacionadas con problemas transitorios se pueden volver a intentar. Por otro lado, las respuestas relacionadas con errores permanentes indican que debes hacer cambios, como cambios en la autorización o en la configuración, antes de que sea útil volver a intentar la solicitud. Las siguientes respuestas indican problemas transitorios que se pueden volver a intentar:
- Códigos de respuesta HTTP
408
,429
y5xx
. - Tiempos de espera de sockets y desconexiones TCP.
Para obtener más información, consulta los códigos de estado y de error de JSON y XML.
Idempotencia
Las solicitudes idempotentes se pueden ejecutar repetidamente sin cambiar el estado final del recurso de destino, lo que da como resultado el mismo estado final cada vez. Por ejemplo, las operaciones de lista siempre son idempotentes, ya que estas solicitudes no modifican los recursos. Por otro lado, crear una notificación de Pub/Sub nunca es idempotente, ya que se crea un nuevo ID de notificación cada vez que la solicitud se completa correctamente.
A continuación se muestran ejemplos de condiciones que hacen que una operación sea idempotente:
La operación tiene el mismo efecto observable en el recurso de destino incluso cuando se solicita continuamente.
La operación solo se realiza correctamente una vez.
La operación no tiene ningún efecto observable en el estado del recurso de destino.
Cuando recibas una respuesta que se pueda volver a intentar, debes tener en cuenta la idempotencia de la solicitud, ya que volver a intentar solicitudes que no son idempotentes puede provocar condiciones de carrera y otros conflictos.
Idempotencia condicional
Un subconjunto de solicitudes son condicionalmente idempotentes, lo que significa que solo son idempotentes si incluyen argumentos opcionales específicos. Las operaciones que se pueden reintentar de forma segura solo se deben reintentar de forma predeterminada si se cumple la condición. Cloud Storage acepta condiciones previas y ETags como casos de condiciones para las solicitudes.
Idempotencia de las operaciones
En la siguiente tabla se enumeran las operaciones de Cloud Storage que se incluyen en cada categoría de idempotencia.
Idempotencia | Operaciones |
---|---|
Siempre idempotente |
|
Idempotente condicionalmente |
|
Nunca idempotente |
|
1 Este campo se puede usar en la API JSON. Para ver los campos que se pueden usar en las bibliotecas de cliente, consulta la documentación de la biblioteca de cliente correspondiente.
Cómo implementan las herramientas de Cloud Storage las estrategias de reintento
Consola
La consola Google Cloud envía solicitudes a Cloud Storage en tu nombre y gestiona cualquier retroceso necesario.
Línea de comandos
Los comandos gcloud storage
vuelven a intentar los errores que se indican en la sección Respuesta sin que tengas que hacer nada más.
Es posible que tengas que tomar medidas para corregir otros errores, como los siguientes:
Credenciales no válidas o permisos insuficientes.
No se puede acceder a la red debido a un problema de configuración del proxy.
En el caso de los errores que se pueden volver a intentar, la CLI de gcloud vuelve a enviar las solicitudes mediante una estrategia de retirada exponencial binaria truncada. El número predeterminado de reintentos máximos es 32 para la CLI de gcloud.
Bibliotecas de cliente
C++
De forma predeterminada, las operaciones admiten reintentos para los siguientes códigos de error HTTP, así como para cualquier error de socket que indique que la conexión se ha perdido o que nunca se ha establecido correctamente.
408 Request Timeout
429 Too Many Requests
500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
Todos los ajustes de retroceso exponencial y reintento de la biblioteca de C++ se pueden configurar. Si los algoritmos implementados en la biblioteca no se ajustan a tus necesidades, puedes proporcionar código personalizado para implementar tus propias estrategias.
Ajuste | Valor predeterminado |
---|---|
Reintento automático | Verdadero |
Tiempo máximo para reintentar una solicitud | 15 minutos |
Tiempo de espera inicial (retirada) | 1 segundo |
Multiplicador del tiempo de espera por iteración | 2 |
Tiempo máximo de espera | 5 minutos |
De forma predeterminada, la biblioteca de C++ vuelve a intentar todas las operaciones con errores que se pueden volver a intentar, incluso las que nunca son idempotentes y pueden eliminar o crear varios recursos cuando se realizan correctamente varias veces. Para volver a intentar solo las operaciones idempotentes, usa la clase google::cloud::storage::StrictIdempotencyPolicy
.
C#
La biblioteca de cliente de C# usa el retroceso exponencial de forma predeterminada.
Go
De forma predeterminada, las operaciones admiten reintentos en caso de que se produzcan los siguientes errores:
- Errores de conexión:
io.ErrUnexpectedEOF
: esto puede ocurrir debido a problemas de red transitorios.url.Error
que contieneconnection refused
: esto puede ocurrir debido a problemas de red temporales.url.Error
que contieneconnection reset by peer
: Esto significa que Google Cloud ha restablecido la conexión.net.ErrClosed
: esto significa que Google Cloud ha cerrado la conexión.
- Códigos HTTP:
408 Request Timeout
429 Too Many Requests
500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
- Errores que implementan la interfaz
Temporary()
y dan un valor deerr.Temporary() == true
- Cualquiera de los errores anteriores que se haya envuelto con envoltura de errores de Go 1.13
Todos los ajustes de retroceso exponencial de la biblioteca de Go se pueden configurar. De forma predeterminada, las operaciones de Go usan los siguientes ajustes para la retirada exponencial (los valores predeterminados se toman de gax):
Ajuste | Valor predeterminado (en segundos) |
---|---|
Reintento automático | True si es idempotente |
Número máximo de intentos | Sin límite |
Retraso inicial de reintento | 1 segundo |
Multiplicador del retraso de reintento | 2,0 |
Retraso máximo de reintento | 30 segundos |
Tiempo de espera total (fragmento de subida reanudable) | 32 segundos |
Tiempo de espera total (todas las demás operaciones) | Sin límite |
Por lo general, los reintentos continúan indefinidamente a menos que se cancele el contexto de control, se cierre el cliente o se reciba un error no transitorio. Para evitar que se sigan reintentando las operaciones, usa los tiempos de espera de contexto o la cancelación. La única excepción a este comportamiento se da cuando se realizan subidas reanudables con Writer, donde los datos son lo suficientemente grandes como para requerir varias solicitudes. En este caso, cada fragmento agota el tiempo de espera y deja de reintentarse después de 32 segundos de forma predeterminada. Puedes ajustar el tiempo de espera predeterminado cambiando Writer.ChunkRetryDeadline
.
Hay un subconjunto de operaciones de Go que son condicionalmente idempotentes (se pueden reintentar de forma segura en determinadas condiciones). Estas operaciones solo se vuelven a intentar si cumplen condiciones específicas:
GenerationMatch
oGeneration
- Se puede volver a intentar si se ha aplicado una condición previa
GenerationMatch
a la llamada o si se ha definidoObjectHandle.Generation
.
- Se puede volver a intentar si se ha aplicado una condición previa
MetagenerationMatch
- Se puede volver a intentar si se ha aplicado una condición previa
MetagenerationMatch
a la llamada.
- Se puede volver a intentar si se ha aplicado una condición previa
Etag
- Se puede volver a intentar si el método inserta un
etag
en el cuerpo de la solicitud JSON. Solo se usa enHMACKeyHandle.Update
cuando se ha definidoHmacKeyMetadata.Etag
.
- Se puede volver a intentar si el método inserta un
RetryPolicy
tiene el valor RetryPolicy.RetryIdempotent
de forma predeterminada. Consulta Personalizar reintentos para ver ejemplos de cómo modificar el comportamiento predeterminado de los reintentos.
Java
De forma predeterminada, las operaciones admiten reintentos en caso de que se produzcan los siguientes errores:
- Errores de conexión:
Connection reset by peer
: esto significa que Google Cloud ha restablecido la conexión.Unexpected connection closure
: esto significa que Google Cloud ha cerrado la conexión.
- Códigos HTTP:
408 Request Timeout
429 Too Many Requests
500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
Todos los ajustes de retroceso exponencial de la biblioteca de Java se pueden configurar. De forma predeterminada, las operaciones a través de Java usan los siguientes ajustes para el tiempo de espera exponencial:
Ajuste | Valor predeterminado (en segundos) |
---|---|
Reintento automático | True si es idempotente |
Número máximo de intentos | 6 |
Retraso inicial de reintento | 1 segundo |
Multiplicador del retraso de reintento | 2,0 |
Retraso máximo de reintento | 32 segundos |
Tiempo de espera total | 50 segundos |
Tiempo de espera inicial de RPC | 50 segundos |
Multiplicador de tiempo de espera de RPC | 1.0 |
Tiempo de espera máximo de RPC | 50 segundos |
Tiempo de espera de conexión agotado | 20 segundos |
Tiempo de espera de lectura | 20 segundos |
Para obtener más información sobre los ajustes, consulta la documentación de referencia de Java sobre RetrySettings.Builder
y HttpTransportOptions.Builder
.
Hay un subconjunto de operaciones de Java que son condicionalmente idempotentes (se pueden reintentar de forma condicional). Estas operaciones solo se reintentan si incluyen argumentos específicos:
ifGenerationMatch
ogeneration
- Es seguro volver a intentarlo si se ha introducido
ifGenerationMatch
ogeneration
como opción del método.
- Es seguro volver a intentarlo si se ha introducido
ifMetagenerationMatch
- Es seguro volver a intentarlo si se ha pasado
ifMetagenerationMatch
como opción.
- Es seguro volver a intentarlo si se ha pasado
StorageOptions.setStorageRetryStrategy
tiene el valor StorageRetryStrategy#getDefaultStorageRetryStrategy
de forma predeterminada.
Consulta Personalizar reintentos para ver ejemplos de cómo modificar el comportamiento de reintento predeterminado.
Node.js
De forma predeterminada, las operaciones admiten reintentos para los siguientes códigos de error:
- Errores de conexión:
EAI_again
: se trata de un error de petición de DNS. Para obtener más información, consulta la documentación degetaddrinfo
.Connection reset by peer
: esto significa que Google Cloud ha restablecido la conexión.Unexpected connection closure
: esto significa que Google Cloud ha cerrado la conexión.
- Códigos HTTP:
408 Request Timeout
429 Too Many Requests
500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
Todos los ajustes de retroceso exponencial de la biblioteca Node.js se pueden configurar. De forma predeterminada, las operaciones a través de Node.js utilizan los siguientes ajustes para el tiempo de espera exponencial:
Ajuste | Valor predeterminado (en segundos) |
---|---|
Reintento automático | True si es idempotente |
Número máximo de reintentos | 3 |
Tiempo de espera inicial | 1 segundo |
Multiplicador del tiempo de espera por iteración | 2 |
Tiempo máximo de espera | 64 segundos |
Fecha límite predeterminada | 600 segundos |
Hay un subconjunto de operaciones de Node.js que son condicionalmente idempotentes (es decir, se pueden reintentar de forma segura en determinadas condiciones). Estas operaciones solo se vuelven a intentar si incluyen argumentos específicos:
ifGenerationMatch
ogeneration
- Es seguro volver a intentarlo si se ha introducido
ifGenerationMatch
ogeneration
como opción del método. A menudo, los métodos solo aceptan uno de estos dos parámetros.
- Es seguro volver a intentarlo si se ha introducido
ifMetagenerationMatch
- Es seguro volver a intentarlo si se ha pasado
ifMetagenerationMatch
como opción.
- Es seguro volver a intentarlo si se ha pasado
retryOptions.idempotencyStrategy
tiene el valor IdempotencyStrategy.RetryConditional
de forma predeterminada. Consulta Personalizar reintentos para ver ejemplos de cómo modificar el comportamiento predeterminado de los reintentos.
PHP
La biblioteca de cliente de PHP usa el retroceso exponencial de forma predeterminada.
De forma predeterminada, las operaciones admiten reintentos para los siguientes códigos de error:
- Errores de conexión:
connetion-refused
: puede deberse a problemas de red temporales.connection-reset
: esto significa que Google Cloud ha restablecido la conexión.
- Códigos HTTP:
200
: para casos de descarga parcial408 Request Timeout
429 Too Many Requests
500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
Algunos ajustes de retroceso exponencial de la biblioteca PHP se pueden configurar. De forma predeterminada, las operaciones a través de PHP usan los siguientes ajustes para el tiempo de espera exponencial:
Ajuste | Valor predeterminado (en segundos) |
---|---|
Reintento automático | True si es idempotente |
Retraso inicial de reintento | 1 segundo |
Multiplicador del retraso de reintento | 2,0 |
Retraso máximo de reintento | 60 segundos |
Tiempo de espera de solicitud | 0 con REST y 60 con gRPC |
Número de reintentos predeterminado | 3 |
Hay un subconjunto de operaciones de PHP que son condicionalmente idempotentes (se pueden reintentar de forma segura en determinadas condiciones). Estas operaciones solo se vuelven a intentar si incluyen argumentos específicos:
ifGenerationMatch
ogeneration
- Es seguro volver a intentarlo si se ha introducido
ifGenerationMatch
ogeneration
como opción del método. A menudo, los métodos solo aceptan uno de estos dos parámetros.
- Es seguro volver a intentarlo si se ha introducido
ifMetagenerationMatch
- Es seguro volver a intentarlo si se ha pasado
ifMetagenerationMatch
como opción.
- Es seguro volver a intentarlo si se ha pasado
Al crear StorageClient
, se usa la estrategia StorageClient::RETRY_IDEMPOTENT
de forma predeterminada. Consulta Personalizar reintentos para ver ejemplos de cómo modificar el comportamiento predeterminado de los reintentos.
Python
De forma predeterminada, las operaciones admiten reintentos para los siguientes códigos de error:
- Errores de conexión:
requests.exceptions.ConnectionError
requests.exceptions.ChunkedEncodingError
(solo para operaciones que obtienen o envían datos de carga útil a objetos, como las subidas y descargas)ConnectionError
http.client.ResponseNotReady
urllib3.exceptions.TimeoutError
- Códigos HTTP:
408 Request Timeout
429 Too Many Requests
500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
Las operaciones a través de Python usan los siguientes ajustes predeterminados para la retirada exponencial:
Ajuste | Valor predeterminado (en segundos) |
---|---|
Reintento automático | True si es idempotente |
Tiempo de espera inicial | 1 |
Multiplicador del tiempo de espera por iteración | 2 |
Tiempo máximo de espera | 60 |
Fecha límite predeterminada | 120 |
Además de las operaciones de Cloud Storage que son siempre idempotentes, la biblioteca de cliente de Python vuelve a intentar automáticamente las operaciones Objects: insert, Objects: delete y Objects: patch de forma predeterminada.
Hay un subconjunto de operaciones de Python que son condicionalmente idempotentes (se pueden volver a intentar de forma segura) cuando incluyen argumentos específicos. Estas operaciones solo se vuelven a intentar si se cumple un caso de condición:
DEFAULT_RETRY_IF_GENERATION_SPECIFIED
- Se puede volver a intentar si se ha pasado
generation
oif_generation_match
como argumento al método. A menudo, los métodos solo aceptan uno de estos dos parámetros.
- Se puede volver a intentar si se ha pasado
DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED
- Se puede volver a intentar si
if_metageneration_match
se ha enviado como argumento al método.
- Se puede volver a intentar si
DEFAULT_RETRY_IF_ETAG_IN_JSON
- Se puede volver a intentar si el método inserta un
etag
en el cuerpo de la solicitud JSON. En el caso deHMACKeyMetadata.update()
, esto significa que el etag debe definirse en el propio objetoHMACKeyMetadata
. En el caso del métodoset_iam_policy()
de otras clases, esto significa que el etag debe definirse en el argumento "policy" que se pasa al método.
- Se puede volver a intentar si el método inserta un
Ruby
De forma predeterminada, las operaciones admiten reintentos para los siguientes códigos de error:
- Errores de conexión:
SocketError
HTTPClient::TimeoutError
Errno::ECONNREFUSED
HTTPClient::KeepAliveDisconnected
- Códigos HTTP:
408 Request Timeout
429 Too Many Requests
5xx Server Error
Todos los ajustes de retroceso exponencial de la biblioteca de cliente de Ruby se pueden configurar. De forma predeterminada, las operaciones a través de la biblioteca de cliente de Ruby usan los siguientes ajustes para la retención exponencial:
Ajuste | Valor predeterminado |
---|---|
Reintento automático | Verdadero |
Número máximo de reintentos | 3 |
Tiempo de espera inicial | 1 segundo |
Multiplicador del tiempo de espera por iteración | 2 |
Tiempo máximo de espera | 60 segundos |
Fecha límite predeterminada | 900 segundos |
Hay un subconjunto de operaciones de Ruby que son condicionalmente idempotentes (es decir, se pueden volver a intentar de forma segura) cuando incluyen argumentos específicos:
if_generation_match
ogeneration
- Se puede volver a intentar si se pasa el parámetro
generation
oif_generation_match
como argumento al método. A menudo, los métodos solo aceptan uno de estos dos parámetros.
- Se puede volver a intentar si se pasa el parámetro
if_metageneration_match
- Se puede volver a intentar si el parámetro
if_metageneration_match
se pasa como una opción.
- Se puede volver a intentar si el parámetro
De forma predeterminada, se vuelve a intentar realizar todas las operaciones idempotentes y las operaciones idempotentes condicionales solo si se cumple la condición. Las operaciones no idempotentes no se vuelven a intentar. Consulta Personalizar reintentos para ver ejemplos de cómo modificar el comportamiento predeterminado de los reintentos.
APIs REST
Cuando llames directamente a la API JSON o XML, debes usar el algoritmo de tiempo de espera exponencial para implementar tu propia estrategia de reintentos.
Personalizar reintentos
Consola
No puedes personalizar el comportamiento de los reintentos mediante la Google Cloud consola.
Línea de comandos
En el caso de los comandos gcloud storage
, puede controlar la estrategia de reintento
creando una configuración con nombre y definiendo algunas o todas las
propiedades siguientes:
Ajuste | Valor predeterminado (en segundos) |
---|---|
base_retry_delay |
1 |
exponential_sleep_multiplier |
2 |
max_retries |
32 |
max_retry_delay |
32 |
A continuación, aplica la configuración definida por comando mediante la marca --configuration
de todo el proyecto o para todos los comandos de la CLI de Google Cloud mediante el comando gcloud config set
.
Bibliotecas de cliente
C++
Para personalizar el comportamiento de reintento, proporciona valores para las siguientes opciones
cuando inicialices el objeto google::cloud::storage::Client
:
google::cloud::storage::RetryPolicyOption
: la biblioteca proporciona las clasesgoogle::cloud::storage::LimitedErrorCountRetryPolicy
ygoogle::cloud::storage::LimitedTimeRetryPolicy
. Puedes proporcionar tu propia clase, que debe implementar la interfazgoogle::cloud::RetryPolicy
.google::cloud::storage::BackoffPolicyOption
: la biblioteca proporciona la clasegoogle::cloud::storage::ExponentialBackoffPolicy
. Puedes proporcionar tu propia clase, que debe implementar la interfazgoogle::cloud::storage::BackoffPolicy
.google::cloud::storage::IdempotencyPolicyOption
: la biblioteca proporciona las clasesgoogle::cloud::storage::StrictIdempotencyPolicy
ygoogle::cloud::storage::AlwaysRetryIdempotencyPolicy
. Puedes proporcionar tu propia clase, que debe implementar la interfazgoogle::cloud::storage::IdempotencyPolicy
.
Para obtener más información, consulta la documentación de referencia de la biblioteca de cliente de C++.
C#
No puedes personalizar la estrategia de reintento predeterminada que usa la biblioteca de cliente de C#.
Go
Cuando inicializas un cliente de almacenamiento, se establece una configuración de reintentos predeterminada. A menos que se anulen, las opciones de la configuración se definen con los valores predeterminados. Los usuarios pueden configurar un comportamiento de reintento no predeterminado para una sola llamada de biblioteca (con BucketHandle.Retryer y ObjectHandle.Retryer) o para todas las llamadas realizadas por un cliente (con Client.SetRetry). Para modificar el comportamiento de reintento, pasa las RetryOptions pertinentes a uno de estos métodos.
Consulta el siguiente código de ejemplo para saber cómo personalizar el comportamiento de los reintentos.
Java
Cuando inicializas Storage
, también se inicializa una instancia de RetrySettings
. Si no se anulan, las opciones de RetrySettings
se definen con los valores predeterminados. Para modificar el comportamiento predeterminado de reintento automático, pasa el StorageRetryStrategy
personalizado al StorageOptions
usado para crear la instancia Storage
. Para modificar cualquiera de los otros parámetros escalares, pasa un RetrySettings
personalizado al StorageOptions
usado para crear la instancia Storage
.
Consulta el siguiente ejemplo para saber cómo personalizar el comportamiento de reintento:
Node.js
Cuando inicializas Cloud Storage, también se inicializa un archivo de configuración retryOptions. A menos que se anulen, las opciones de la configuración se definen con los valores predeterminados. Para modificar el comportamiento predeterminado de los reintentos, pasa la configuración de reintento personalizada retryOptions
al constructor de almacenamiento al inicializarlo.
La biblioteca de cliente de Node.js puede usar automáticamente estrategias de retardo exponencial para volver a intentar enviar solicitudes con el parámetro autoRetry
.
Consulta el siguiente código de ejemplo para saber cómo personalizar el comportamiento de los reintentos.
PHP
Cuando inicializas un cliente de almacenamiento, se establece una configuración de reintentos predeterminada. A menos que se anulen, las opciones de la configuración se definen con los valores predeterminados. Los usuarios pueden configurar un comportamiento de reintento no predeterminado para un cliente o una sola llamada de operación pasando opciones de anulación en una matriz.
Consulta el siguiente código de ejemplo para saber cómo personalizar el comportamiento de los reintentos.
Python
Para modificar el comportamiento predeterminado de los reintentos, crea una copia del objeto google.cloud.storage.retry.DEFAULT_RETRY
llamándolo con un método with_BEHAVIOR
. La biblioteca de cliente de Python usa automáticamente estrategias de retardo para reintentar las solicitudes si incluyes el parámetro DEFAULT_RETRY
.
Ten en cuenta que with_predicate
no se admite en operaciones que obtienen o envían datos de carga útil a objetos, como las subidas y las descargas. Te recomendamos que modifiques los atributos uno a uno. Para obtener más información, consulta la referencia de reintentos de google-api-core.
Para configurar tu propio reintento condicional, crea un objeto ConditionalRetryPolicy
y encapsula tu objeto Retry
personalizado con DEFAULT_RETRY_IF_GENERATION_SPECIFIED
, DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED
o DEFAULT_RETRY_IF_ETAG_IN_JSON
.
Consulta el siguiente código de ejemplo para saber cómo personalizar el comportamiento de los reintentos.
Ruby
Cuando inicializas el cliente de almacenamiento, todas las configuraciones de reintentos se definen con los valores que se muestran en la tabla anterior. Para modificar el comportamiento predeterminado de reintento, pasa las configuraciones de reintento al inicializar el cliente de almacenamiento.
Para anular el número de reintentos de una operación concreta, envía retries
en el parámetro options
de la operación.
APIs REST
Usa el algoritmo de tiempo de espera exponencial para implementar tu propia estrategia de reintentos.
Algoritmo de tiempo de espera exponencial
Un algoritmo de tiempo de espera exponencial vuelve a intentar enviar las solicitudes con tiempos de espera que aumentan exponencialmente entre las solicitudes, hasta un tiempo de espera máximo. Por lo general, debes usar un tiempo de espera exponencial con jitter para volver a enviar las solicitudes que cumplan los criterios de respuesta e idempotencia. Para consultar las prácticas recomendadas para implementar reintentos automáticos con tiempo de espera exponencial, consulte Addressing Cascading Failures (Cómo abordar los fallos en cascada).
Antipatrones de reintento
Te recomendamos que uses o personalices los mecanismos de reintento integrados cuando sea posible. Consulta Personalizar reintentos. Tanto si usas los mecanismos de reintento predeterminados como si los personalizas o implementas tu propia lógica de reintento, es fundamental evitar los siguientes antipatrones comunes, ya que pueden agravar los problemas en lugar de resolverlos.
Reintentando sin tiempo de espera
Si se reintenta enviar solicitudes inmediatamente o con retrasos muy cortos, se pueden producir fallos en cascada, es decir, fallos que pueden desencadenar otros fallos.
Cómo evitarlo: implementa un tiempo de espera exponencial con fluctuación. Esta estrategia aumenta progresivamente el tiempo de espera entre reintentos y añade un elemento aleatorio para evitar que los reintentos sobrecarguen el servicio.
Volver a intentar operaciones no idempotentes de forma incondicional
Si se ejecutan repetidamente operaciones que no son idempotentes, se pueden producir efectos secundarios no deseados, como sobrescrituras o eliminaciones de datos no deseadas.
Cómo evitarlo: consulta las características de idempotencia de cada operación en la sección sobre la idempotencia de las operaciones. En el caso de las operaciones no idempotentes, asegúrate de que tu lógica de reintentos pueda gestionar los posibles duplicados o evita reintentarlas por completo. Tenga cuidado con los reintentos que puedan provocar condiciones de carrera.
Reintentar errores que no se pueden reintentar
Tratar todos los errores como si se pudieran volver a intentar puede ser problemático. Algunos errores, como los fallos de autorización o las solicitudes no válidas, son persistentes. Si se vuelve a intentar realizar la acción sin solucionar la causa subyacente, no se completará correctamente y es posible que las aplicaciones se queden en un bucle infinito.
Cómo evitarlo: clasifica los errores en transitorios (se pueden volver a intentar) y permanentes (no se pueden volver a intentar). Solo se deben reintentar los errores transitorios, como los códigos HTTP 408
, 429
y 5xx
, o los problemas de conexión específicos. En el caso de los errores permanentes, regístralos y gestiona la causa subyacente de forma adecuada.
Ignorar los límites de reintentos
Si se reintenta indefinidamente, se pueden agotar los recursos de la aplicación o se pueden enviar solicitudes continuamente a un servicio que no se recuperará sin intervención.
Cómo evitarlo: adapta los límites de reintentos a la naturaleza de tu carga de trabajo. En el caso de las cargas de trabajo sensibles a la latencia, te recomendamos que definas una duración máxima total de reintentos para asegurarte de que se produzca una respuesta o un fallo a tiempo. En el caso de las cargas de trabajo por lotes, que pueden tolerar periodos de reintento más largos para errores transitorios del lado del servidor, considera la posibilidad de definir un límite de reintentos total más alto.
Reintentos innecesarios
Si se añade una lógica de reintento personalizada a nivel de aplicación sobre los mecanismos de reintento ya existentes, se puede producir un número excesivo de reintentos. Por ejemplo, si tu aplicación vuelve a intentar una operación tres veces y la biblioteca de cliente subyacente también lo hace tres veces por cada intento de tu aplicación, podrías acabar con nueve intentos. Si se envían muchos reintentos para errores que no se pueden reintentar, se puede limitar el número de solicitudes, lo que a su vez limita el rendimiento de todas las cargas de trabajo. Un número elevado de reintentos también puede aumentar la latencia de las solicitudes sin mejorar la tasa de éxito.
Cómo evitarlo: te recomendamos que uses y configures los mecanismos de reintento integrados. Si debes implementar reintentos a nivel de aplicación, como en el caso de una lógica empresarial específica que abarca varias operaciones, hazlo conociendo bien el comportamiento de reintento subyacente. Considera inhabilitar o limitar significativamente los reintentos en una de las capas para evitar efectos multiplicativos.