Estrategia de reintentos

En esta página, se describe cómo las herramientas de Cloud Storage reintentan las solicitudes fallidas y cómo personalizar el comportamiento de los reintentos. También se describen las consideraciones para reintentar solicitudes.

Descripción general

Existen dos factores que determinan si una solicitud es segura o no:

  1. La respuesta que recibes de la solicitud
  2. La idempotencia de la solicitud.

Respuesta

La respuesta que recibes de tu solicitud indica si es útil reintentar la solicitud. Por lo general, las respuestas relacionadas con los problemas transitorios se pueden reintentar. Por otro lado, la respuesta relacionada con errores permanentes indica que debes realizar cambios, como cambios de autorización o configuración, antes de que sea útil reintentar la solicitud. Las siguientes respuestas indican problemas transitorios que son útiles para reintentar:

  • Códigos de respuesta HTTP 4084295xx.
  • Tiempos de espera de sockets agotados y desconexiones de TCP

Si quieres obtener más información, consulta los códigos de estado y error para JSON y XML.

Idempotencia

Una solicitud que es idempotente significa que se puede realizar de manera reiterada y que siempre deja el recurso de destino en el mismo estado final. Por ejemplo, las solicitudes de listas siempre son idempotentes, ya que estas solicitudes no modifican recursos. Por otro lado, crear una notificación de Pub/Sub nueva nunca es idempotente, ya que crea un ID de notificación nuevo cada vez que la solicitud se realiza de forma correcta.

Los siguientes son ejemplos de condiciones que hacen que una operación sea idempotente:

  • La operación tiene el mismo efecto observable en el recurso objetivo incluso cuando se solicita de forma continua.

  • La operación solo se realiza una vez.

  • La operación no tiene un efecto observable en el estado del recurso de destino.

Cuando recibes una respuesta que se puede reintentar, debes considerar la idempotencia de la solicitud, ya que reintentar solicitudes que no son idempotentes puede generar condiciones de carrera y otros conflictos.

Idempotencia condicional

Un subconjunto de solicitudes es condicionalmente idempotente, lo que significa que solo son idempotentes si incluyen argumentos opcionales específicos. Las operaciones condicionalmente seguras para su reintento solo deben reintentarse de forma predeterminada si se aprueba el caso de la condición. Cloud Storage acepta condiciones previas y ETag como casos de condición para las solicitudes.

Idempotencia de operaciones

En la siguiente tabla, se describen las operaciones de Cloud Storage que corresponden a cada categoría de idempotencia.

Idempotencia Operations
Siempre idempotente
  • Todas las solicitudes get y list
  • Inserta o borra buckets
  • Políticas y permisos de IAM del bucket de prueba
  • Bloquear políticas de retención
  • Borra una clave HMAC o una notificación de Pub/Sub
Condicionalmente idempotente
  • Solicitudes de actualización o parche para buckets con IfMetagenerationMatch o ETag como condición previa HTTP
  • Solicitudes de actualización o parche para objetos con IfMetagenerationMatch o ETag como condición previa HTTP
  • Establece una política de IAM del bucket con ETag como condición previa HTTP o en el cuerpo del recurso
  • Actualiza una clave HMAC con ETag como condición previa HTTP o en el cuerpo del recurso
  • Inserta, copia, redacta o reescribe objetos con ifGenerationMatch
  • Borra un objeto con ifGenerationMatch (o con un número de generación para versiones de objetos)
Nunca idempotente
  • Crea una clave HMAC
  • Crea una notificación de Pub/Sub
  • Crea, borra o envía solicitudes de parche o actualización para las LCA de buckets y objetos o las LCA de objeto predeterminadas

Cómo las herramientas de Cloud Storage implementan estrategias de reintento

Consola

La consola de Google Cloud envía solicitudes a Cloud Storage en tu nombre y controla las retiradas necesarias.

Línea de comandos

Los comandos gcloud storage vuelven a intentar los errores enumerados en la sección Respuesta sin que debas realizar ninguna acción adicional. Es posible que debas tomar medidas en caso de 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.

Para los errores que se pueden intentar de nuevo, gcloud CLI vuelve a intentar las solicitudes a través de una estrategia de retirada exponencial binaria truncada. La cantidad predeterminada de reintentos máximos es 32 para la gcloud CLI.

Bibliotecas cliente

C++

De forma predeterminada, las operaciones admiten reintentos para los siguientes códigos de error de HTTP, así como cualquier error de socket que indique que se perdió la conexión o que nunca se estableció de forma correcta.

  • 408 Request Timeout
  • 429 Too Many Requests
  • 500 Internal Server Error
  • 502 Bad Gateway
  • 503 Service Unavailable
  • 504 Gateway Timeout

Todas las opciones de retirada exponencial y de reintentos en la biblioteca de C++ se pueden configurar. Si los algoritmos implementados en la biblioteca no satisfacen tus necesidades, puedes proporcionar un código personalizado para implementar tus propias estrategias.

Configuración Valor predeterminado
Reintento automático Verdadero
Tiempo máximo de reintentos de una solicitud 15 minutos
Tiempo de espera (retirada) inicial 1 segundo
Multiplicador de tiempo de espera por iteración 2
Tiempo máximo de espera 5 minutos

Según la configuración predeterminada, la biblioteca de C++ reintenta todas las operaciones con errores que se pueden reintentar, incluso aquellas que nunca son idempotentes y pueden borrar o crear varios recursos cuando se realizan con éxito de forma repetida. Para reintentar solo las operaciones idempotentes, usa la clase google::cloud::storage::StrictIdempotencyPolicy.

C#

La biblioteca cliente C# usa la retirada exponencial de forma predeterminada.

Comienza a usarlo

De forma predeterminada, las operaciones admiten reintentos para los siguientes errores:

  • Errores de conexión
    • io.ErrUnexpectedEOF: Esto puede ocurrir debido a problemas transitorios de la red.
    • url.Error que contiene connection refused: Esto puede ocurrir debido a problemas transitorios de la red.
    • url.Error que contiene connection reset by peer: Esto significa que Google Cloud restableció la conexión.
    • net.ErrClosed: Esto significa que Google Cloud cerró 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 de err.Temporary() == true
  • Cualquiera de los errores anteriores que se unieron a través de la unión de errores de Go 1.13

Todos los parámetros de configuración de retirada exponencial de la biblioteca GO se puede configurar. De forma predeterminada, las operaciones en Go usan la siguiente configuración para la retirada exponencial (los valores predeterminados se toman de gax):

Configuración Valor predeterminado (en segundos)
Reintento automático Verdadero si es idempotente
Cantidad máxima de intentos Sin límite
Demora inicial hasta reintento 1 segundo
Multiplicador de demora de reintentos 2.0
Retraso máximo de reintentos 30 segundos
Tiempo de espera total (fragmento de carga reanudable) 32 segundos
Tiempo de espera total (todas las demás operaciones) Sin límite

En general, los reintentos continúan de forma indefinida, a menos que se cancele el contexto de control, el cliente se cierre o se reciba un error no transitorio. Para evitar que los reintentos continúen, usa los tiempos de espera de contexto o la cancelación. La única excepción a este comportamiento es cuando se realizan cargas reanudables a través de Writer, en las que los datos son lo suficientemente grandes como para que se requieran varias solicitudes. En esta situación, cada fragmento agota el tiempo de espera y deja de reintentar después de 32 segundos de forma predeterminada. Puedes cambiar el tiempo de espera predeterminado si cambias Writer.ChunkRetryDeadline.

Hay un subconjunto de operaciones de Go que son idempotentes de forma condicional (condicionalmente seguras para reintentar). Estas operaciones solo se reintentan si cumplen con condiciones específicas:

  • GenerationMatch o Generation

    • Es seguro volver a intentarlo si se aplicó una condición previa GenerationMatch a la llamada o si se configuró ObjectHandle.Generation.
  • MetagenerationMatch

    • Es seguro volver a intentarlo si se aplicó una condición previa MetagenerationMatch a la llamada.
  • Etag

    • Es seguro reintentarlo si el método inserta un etag en el cuerpo de la solicitud JSON. Solo se usa en HMACKeyHandle.Update cuando se establece HmacKeyMetadata.Etag.

RetryPolicy se establece en RetryPolicy.RetryIdempotent de forma predeterminada. Consulta la sección Personaliza reintentos a continuación para obtener ejemplos para modificar el comportamiento de reintento predeterminado.

Java

De forma predeterminada, las operaciones admiten reintentos para los siguientes errores:

  • Errores de conexión
    • Connection reset by peer: Esto significa que Google Cloud restableció la conexión.
    • Unexpected connection closure: Esto significa que Google Cloud cerró 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 parámetros de configuración de retirada exponencial de la biblioteca Java se puede configurar. De forma predeterminada, las operaciones a través de Java usan la siguiente configuración para la retirada exponencial:

Configuración Valor predeterminado (en segundos)
Reintento automático Verdadero si es idempotente
Cantidad máxima de intentos 6
Demora inicial hasta reintento 1 segundo
Multiplicador de demora de reintentos 2.0
Retraso máximo de reintentos 32 segundos
Tiempo de espera total 50 segundos
Tiempo de espera de RPC inicial 50 segundos
Multiplicador de tiempo de espera de RPC 1.0
Tiempo de espera máximo de RPC 50 segundos
Se agotó el tiempo de espera de la conexión 20 segundos
Tiempo de espera de lectura 20 segundos

Si deseas obtener más información de los parámetros anteriores, consulta la documentación de referencia de Java de RetrySettings.Builder y HttpTransportOptions.Builder.

Hay un subconjunto de operaciones de Java que son idempotentes de forma condicional (condicionalmente seguras para reintentar). Estas operaciones solo se reintentan si incluyen argumentos específicos:

  • ifGenerationMatch o generation

    • Es seguro reintentarlo si ifGenerationMatch o generation se aprobaron como opción del método.
  • ifMetagenerationMatch

    • Es seguro volver a intentarlo si ifMetagenerationMatch se pasó como una opción.

StorageOptions.setStorageRetryStrategy se establece en StorageRetryStrategy#getDefaultStorageRetryStrategy de forma predeterminada. Consulta la sección Personaliza reintentos a continuación para obtener ejemplos para 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: Este es un error de búsqueda de DNS. Puedes obtener más información en este vínculo.
    • Connection reset by peer: Esto significa que Google Cloud restableció la conexión.
    • Unexpected connection closure: Esto significa que Google Cloud cerró 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

Toda la configuración de retirada exponencial de la biblioteca Node.js se puede configurar. De forma predeterminada, las operaciones a través de Node.js usan la siguiente configuración para la retirada exponencial:

Configuración Valor predeterminado (en segundos)
Reintento automático Verdadero si es idempotente
Cantidad máxima de reintentos 3
Tiempo de espera inicial 1 segundo
Multiplicador de tiempo de espera por iteración 2
Tiempo máximo de espera 64 segundos
Plazo predeterminado 600 segundos

Hay un subconjunto de las operaciones Node.js que son idempotentes de forma condicional (condicionalmente seguro para reintentar). Estas operaciones solo se reintentan si incluyen argumentos específicos:

  • ifGenerationMatch o generation

    • Es seguro reintentarlo si ifGenerationMatch o generation se aprobaron como opción del método. A menudo, los métodos solo aceptan uno de estos dos parámetros.
  • ifMetagenerationMatch

    • Es seguro volver a intentarlo si ifMetagenerationMatch se pasó como una opción.

retryOptions.idempotencyStrategy se establece en IdempotencyStrategy.RetryConditional de forma predeterminada. Consulta la sección Personaliza reintentos a continuación para obtener ejemplos para modificar el comportamiento de reintento predeterminado.

PHP

La biblioteca cliente de PHP usa la retirada exponencial de forma predeterminada.

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 recuperan o envían datos de carga útil a objetos, como cargas y descargas)
    • ConnectionError
  • 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 la siguiente configuración predeterminada para la retirada exponencial:

Configuración Valor predeterminado (en segundos)
Reintento automático Verdadero si es idempotente
Tiempo de espera inicial 1
Multiplicador de tiempo de espera por iteración 2
Tiempo máximo de espera 60
Plazo predeterminado 120

Existe un subconjunto de operaciones de Python que son idempotentes de forma condicional (condicionalmente seguras para reintentar) cuando incluyen argumentos específicos. Estas operaciones solo se reintentan si se aprueba un caso de condición:

  • DEFAULT_RETRY_IF_GENERATION_SPECIFIED

    • Es seguro reintentarlo si generation o if_generation_match se aprobaron como argumento del método. A menudo, los métodos solo aceptan uno de estos dos parámetros.
  • DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED

    • Es seguro reintentarlo si if_metageneration_match se aprobó como argumento del método.
  • DEFAULT_RETRY_IF_ETAG_IN_JSON

    • Es seguro reintentarlo si el método inserta un etag en el cuerpo de la solicitud JSON. Para HMACKeyMetadata.update(), esto significa que la ETag se debe configurar en el objeto HMACKeyMetadata. Para el método set_iam_policy() en otras clases, significa que la ETag se debe establecer en el argumento de la “política” que se pasó al método.

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 parámetros de configuración de retirada exponencial en la biblioteca cliente de Ruby se pueden configurar. De forma predeterminada, las operaciones a través de la biblioteca cliente de Ruby usan los siguientes parámetros de configuración para la retirada exponencial:

Configuración Valor predeterminado
Reintento automático Verdadero
Cantidad máxima de reintentos 3
Tiempo de espera inicial 1 segundo
Multiplicador de tiempo de espera por iteración 2
Tiempo máximo de espera 60 segundos
Plazo predeterminado 900 segundos

Existe un subconjunto de operaciones de Ruby que son idempotentes de forma condicional (condicionalmente seguras para reintentar) cuando incluyen argumentos específicos:

  • if_generation_match o generation

    • Es seguro reintentarlo si el parámetro generation o if_generation_match se pasa como un argumento al método. A menudo, los métodos solo aceptan uno de estos dos parámetros.
  • if_metageneration_match

    • Es seguro reintentarlo si el parámetro if_metageneration_match se pasa como una opción.

Según la configuración predeterminada, se reintentan todas las operaciones idempotentes y las operaciones idempotentes de forma condicional se reintentan solo si se aprueba el caso de la condición. No se reintentan las operaciones que no son idempotentes. Consulta la sección Personaliza reintentos a continuación para obtener ejemplos para modificar el comportamiento de reintento predeterminado.

APIs de REST

Cuando llames a la API de XML o JSON de forma directa, debes usar el algoritmo de retirada exponencial para implementar tu propia estrategia de reintento.

Personaliza los reintentos

Consola

No puedes personalizar el comportamiento de los reintentos con la consola de Google Cloud.

Línea de comandos

Para los comandos gcloud storage, puedes controlar la estrategia de reintento si creas una configuración con nombre y configuras algunas o todas las siguientes propiedades:

  • base_retry_delay
  • exponential_sleep_multiplier
  • max_retries
  • max_retry_delay

Luego, debes aplicar la configuración definida por comando a través del uso de la marca--configuration de todo el proyecto o para todos los comandos de gcloud con elcomando gcloud config set.

Bibliotecas 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 clases google::cloud::storage::LimitedErrorCountRetryPolicy y google::cloud::storage::LimitedTimeRetryPolicy. Puedes proporcionar tu propia clase, que debe implementar la interfaz google::cloud::RetryPolicy.

  • google::cloud::storage::BackoffPolicyOption: La biblioteca proporciona la clase google::cloud::storage::ExponentialBackoffPolicy. Puedes proporcionar tu propia clase, que debe implementar la interfaz google::cloud::storage::BackoffPolicy.

  • google::cloud::storage::IdempotencyPolicyOption: La biblioteca proporciona las clases google::cloud::storage::StrictIdempotencyPolicy y google::cloud::storage::AlwaysRetryIdempotencyPolicy. Puedes proporcionar tu propia clase, que debe implementar la interfaz google::cloud::storage::IdempotencyPolicy.

Para obtener más información, consulta la documentación de referencia de la biblioteca cliente de C++.

namespace gcs = ::google::cloud::storage;
// Create the client configuration:
auto options = google::cloud::Options{};
// Retries only idempotent operations.
options.set<gcs::IdempotencyPolicyOption>(
    gcs::StrictIdempotencyPolicy().clone());
// On error, it backs off for a random delay between [1, 3] seconds, then [3,
// 9] seconds, then [9, 27] seconds, etc. The backoff time never grows larger
// than 1 minute.
options.set<gcs::BackoffPolicyOption>(
    gcs::ExponentialBackoffPolicy(
        /*initial_delay=*/std::chrono::seconds(1),
        /*maximum_delay=*/std::chrono::minutes(1),
        /*scaling=*/3.0)
        .clone());
// Retries all operations for up to 5 minutes, including any backoff time.
options.set<gcs::RetryPolicyOption>(
    gcs::LimitedTimeRetryPolicy(std::chrono::minutes(5)).clone());
return gcs::Client(std::move(options));

C#

Por el momento, no puedes personalizar la estrategia de reintento predeterminada que usa la biblioteca cliente de C#.

Comienza a usarlo

Cuando inicializas un cliente de almacenamiento, se establece una configuración de reintento predeterminada. A menos que se anulen, las opciones en la configuración se establecen en los valores predeterminados. Los usuarios pueden configurar el comportamiento de reintento no predeterminado para una sola llamada a la biblioteca (a través de BucketHandle.Retryer y ObjectHandle.Retryer) o para todas las llamadas que realiza un cliente (a través de Client.SetRetry). Para modificar el comportamiento de reintento, pasa las RetryOptions deseadas a uno de estos métodos.

Consulta la siguiente muestra de código para aprender cómo personalizar tu comportamiento de reintento.

import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/storage"
	"github.com/googleapis/gax-go/v2"
)

// configureRetries configures a custom retry strategy for a single API call.
func configureRetries(w io.Writer, bucket, object string) error {
	// bucket := "bucket-name"
	// object := "object-name"
	ctx := context.Background()
	client, err := storage.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("storage.NewClient: %w", err)
	}
	defer client.Close()

	// Configure retries for all operations using this ObjectHandle. Retries may
	// also be configured on the BucketHandle or Client types.
	o := client.Bucket(bucket).Object(object).Retryer(
		// Use WithBackoff to control the timing of the exponential backoff.
		storage.WithBackoff(gax.Backoff{
			// Set the initial retry delay to a maximum of 2 seconds. The length of
			// pauses between retries is subject to random jitter.
			Initial: 2 * time.Second,
			// Set the maximum retry delay to 60 seconds.
			Max: 60 * time.Second,
			// Set the backoff multiplier to 3.0.
			Multiplier: 3,
		}),
		// Use WithPolicy to customize retry so that all requests are retried even
		// if they are non-idempotent.
		storage.WithPolicy(storage.RetryAlways),
	)

	// Use context timeouts to set an overall deadline on the call, including all
	// potential retries.
	ctx, cancel := context.WithTimeout(ctx, 500*time.Second)
	defer cancel()

	// Delete an object using the specified retry policy.
	if err := o.Delete(ctx); err != nil {
		return fmt.Errorf("Object(%q).Delete: %w", object, err)
	}
	fmt.Fprintf(w, "Blob %v deleted with a customized retry strategy.\n", object)
	return nil
}

Java

Cuando inicializas Storage, también se inicializa una instancia de RetrySettings. A menos que se anulen, las opciones de RetrySettings se establecen con los valores predeterminados. Para modificar el comportamiento de reintento automático predeterminado, pasa la StorageRetryStrategy personalizada a las StorageOptions que se usan para construir la instancia de Storage. Si deseas modificar cualquiera de los otros parámetros escalares, pasa una RetrySettings personalizada a las StorageOptions que se usan para construir la instancia de Storage.

Consulta el siguiente ejemplo para aprender cómo personalizar el comportamiento de reintento:


import com.google.api.gax.retrying.RetrySettings;
import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import com.google.cloud.storage.StorageRetryStrategy;
import org.threeten.bp.Duration;

public final class ConfigureRetries {
  public static void main(String[] args) {
    String bucketName = "my-bucket";
    String blobName = "blob/to/delete";
    deleteBlob(bucketName, blobName);
  }

  static void deleteBlob(String bucketName, String blobName) {
    // Customize retry behavior
    RetrySettings retrySettings =
        StorageOptions.getDefaultRetrySettings()
            .toBuilder()
            // Set the max number of attempts to 10 (initial attempt plus 9 retries)
            .setMaxAttempts(10)
            // Set the backoff multiplier to 3.0
            .setRetryDelayMultiplier(3.0)
            // Set the max duration of all attempts to 5 minutes
            .setTotalTimeout(Duration.ofMinutes(5))
            .build();

    StorageOptions alwaysRetryStorageOptions =
        StorageOptions.newBuilder()
            // Customize retry so all requests are retried even if they are non-idempotent.
            .setStorageRetryStrategy(StorageRetryStrategy.getUniformStorageRetryStrategy())
            // provide the previously configured retrySettings
            .setRetrySettings(retrySettings)
            .build();

    // Instantiate a client
    Storage storage = alwaysRetryStorageOptions.getService();

    // Delete the blob
    BlobId blobId = BlobId.of(bucketName, blobName);
    boolean success = storage.delete(blobId);

    System.out.printf(
        "Deletion of Blob %s completed %s.%n", blobId, success ? "successfully" : "unsuccessfully");
  }
}

Node.js

Cuando inicializas Cloud Storage, también se inicializa un archivo de configuración retryOptions. A menos que se anulen, las opciones en la configuración se establecen en los valores predeterminados. Para modificar el comportamiento de reintento predeterminado, pasa la configuración de reintento personalizada retryOptions al constructor de almacenamiento durante la inicialización. La biblioteca cliente de Node.js puede usar estrategias de retirada de forma automática para reintentar solicitudes con el parámetro autoRetry.

Consulta la siguiente muestra de código para aprender cómo personalizar tu comportamiento de reintento.

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The ID of your GCS file
// const fileName = 'your-file-name';

// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage({
  retryOptions: {
    // If this is false, requests will not retry and the parameters
    // below will not affect retry behavior.
    autoRetry: true,
    // The multiplier by which to increase the delay time between the
    // completion of failed requests, and the initiation of the subsequent
    // retrying request.
    retryDelayMultiplier: 3,
    // The total time between an initial request getting sent and its timeout.
    // After timeout, an error will be returned regardless of any retry attempts
    // made during this time period.
    totalTimeout: 500,
    // The maximum delay time between requests. When this value is reached,
    // retryDelayMultiplier will no longer be used to increase delay time.
    maxRetryDelay: 60,
    // The maximum number of automatic retries attempted before returning
    // the error.
    maxRetries: 5,
    // Will respect other retry settings and attempt to always retry
    // conditionally idempotent operations, regardless of precondition
    idempotencyStrategy: IdempotencyStrategy.RetryAlways,
  },
});
console.log(
  'Functions are customized to be retried according to the following parameters:'
);
console.log(`Auto Retry: ${storage.retryOptions.autoRetry}`);
console.log(
  `Retry delay multiplier: ${storage.retryOptions.retryDelayMultiplier}`
);
console.log(`Total timeout: ${storage.retryOptions.totalTimeout}`);
console.log(`Maximum retry delay: ${storage.retryOptions.maxRetryDelay}`);
console.log(`Maximum retries: ${storage.retryOptions.maxRetries}`);
console.log(
  `Idempotency strategy: ${storage.retryOptions.idempotencyStrategy}`
);

async function deleteFileWithCustomizedRetrySetting() {
  await storage.bucket(bucketName).file(fileName).delete();
  console.log(`File ${fileName} deleted with a customized retry strategy.`);
}

deleteFileWithCustomizedRetrySetting();

PHP

En este momento, no puedes personalizar la estrategia de reintento predeterminada que usa la biblioteca cliente de PHP.

Python

Para modificar el comportamiento de reintento predeterminado, crea una copia del objeto google.cloud.storage.retry.DEFAULT_RETRY llamándolo con un método with_XXX. La biblioteca cliente de Python usa estrategias de retirada de forma automática para reintentar las solicitudes si incluyes el parámetro DEFAULT_RETRY.

Ten en cuenta que with_predicate no es compatible con operaciones que recuperan o envían datos de carga útil a objetos, como cargas y descargas. Te recomendamos modificar los atributos uno por uno. Para obtener más información, consulta la referencia de operaciones de reintento de google-api-core.

Para configurar tu propio reintento condicional, crea un objeto ConditionalRetryPolicy y une tu objeto Retry personalizado con DEFAULT_RETRY_IF_GENERATION_SPECIFIED, DEFAULT_RETRY_IF_METAGENERATION_SPECIFIED o DEFAULT_RETRY_IF_ETAG_IN_JSON.

Consulta la siguiente muestra de código para aprender cómo personalizar tu comportamiento de reintento.

from google.cloud import storage
from google.cloud.storage.retry import DEFAULT_RETRY

def configure_retries(bucket_name, blob_name):
    """Configures retries with customizations."""
    # The ID of your GCS bucket
    # bucket_name = "your-bucket-name"
    # The ID of your GCS object
    # blob_name = "your-object-name"

    storage_client = storage.Client()
    bucket = storage_client.bucket(bucket_name)
    blob = bucket.blob(blob_name)

    # Customize retry with a deadline of 500 seconds (default=120 seconds).
    modified_retry = DEFAULT_RETRY.with_deadline(500.0)
    # Customize retry with an initial wait time of 1.5 (default=1.0).
    # Customize retry with a wait time multiplier per iteration of 1.2 (default=2.0).
    # Customize retry with a maximum wait time of 45.0 (default=60.0).
    modified_retry = modified_retry.with_delay(initial=1.5, multiplier=1.2, maximum=45.0)

    # blob.delete() uses DEFAULT_RETRY_IF_GENERATION_SPECIFIED by default.
    # Override with modified_retry so the function retries even if the generation
    # number is not specified.
    print(
        f"The following library method is customized to be retried according to the following configurations: {modified_retry}"
    )

    blob.delete(retry=modified_retry)
    print(f"Blob {blob_name} deleted with a customized retry strategy.")

Ruby

Cuando inicializas el cliente de almacenamiento, todas las opciones de configuración de reintentos se establecen en los valores que se muestran en la tabla anterior. Para modificar el comportamiento de reintento predeterminado, pasa las opciones de configuración de reintento mientras inicializas el cliente de almacenamiento.

Para anular la cantidad de reintentos de una operación en particular, pasa retries en el parámetro options de la operación.

def configure_retries bucket_name: nil, file_name: nil
  # The ID of your GCS bucket
  # bucket_name = "your-unique-bucket-name"

  # The ID of your GCS object
  # file_name = "your-file-name"

  require "google/cloud/storage"

  # Creates a client
  storage = Google::Cloud::Storage.new(

    # The maximum number of automatic retries attempted before returning
    # the error.
    #
    # Customize retry configuration with the maximum retry attempt of 5.
    retries: 5,

    # The total time in seconds that requests are allowed to keep being retried.
    # After max_elapsed_time, an error will be returned regardless of any
    # retry attempts made during this time period.
    #
    # Customize retry configuration with maximum elapsed time of 500 seconds.
    max_elapsed_time: 500,

    # The initial interval between the completion of failed requests, and the
    # initiation of the subsequent retrying request.
    #
    # Customize retry configuration with an initial interval of 1.5 seconds.
    base_interval: 1.5,

    # The maximum interval between requests. When this value is reached,
    # multiplier will no longer be used to increase the interval.
    #
    # Customize retry configuration with maximum interval of 45.0 seconds.
    max_interval: 45,

    # The multiplier by which to increase the interval between the completion
    # of failed requests, and the initiation of the subsequent retrying request.
    #
    # Customize retry configuration with an interval multiplier per iteration of 1.2.
    multiplier: 1.2
  )

  # Uses the retry configuration set during the client initialization above with 5 retries
  file = storage.service.get_file bucket_name, file_name

  # Maximum retry attempt can be overridden for each operation using options parameter.
  storage.service.delete_file bucket_name, file_name, options: { retries: 4 }
  puts "File #{file.name} deleted with a customized retry strategy."
end

APIs de REST

Usa el algoritmo de retirada exponencial para implementar tu propia estrategia de reintento.

Algoritmo de retirada exponencial

Un algoritmo de retirada exponencial reintenta las solicitudes a través del aumento exponencial de los tiempos de espera entre solicitudes, hasta un tiempo de retirada máximo. Por lo general, debes usar la retirada exponencial con jitter para reintentar las solicitudes que cumplan con los criterios de respuesta y de idempotencia. Para obtener prácticas recomendadas sobre la implementación de reintentos automáticos con retirada exponencial, consulta Aborda fallas en cascada.

¿Qué sigue?