Reintentar eventos

Un evento se puede rechazar por varios motivos. Por ejemplo, el servicio de receptor de eventos puede no estar disponible temporalmente debido a una interrupción, el servicio puede encontrar un error al procesar un evento o los recursos del servicio pueden agotarse. Los errores transitorios como este se pueden volver a intentar.

También puede ocurrir que un evento no se entregue al receptor. Por ejemplo, puede que el evento no coincida con el esquema configurado o que la mediación del evento falle antes de que el mensaje del evento se pueda enrutar a su destino final. En estos casos, se producen errores persistentes.

Errores transitorios

Eventarc Advanced te permite gestionar errores transitorios. Estos errores transitorios se pueden volver a intentar e incluyen los que tienen los siguientes códigos de error:

  • HTTP 408 Request Timeout
  • HTTP 409 Conflict
  • HTTP 429 Too Many Requests
  • HTTP 500 Internal Server Error
  • HTTP 502 Bad Gateway
  • HTTP 503 Service Unavailable
  • HTTP 504 Gateway Time-out

Errores persistentes

A diferencia de los errores transitorios, los errores persistentes incluyen los siguientes:

  • Errores que se producen cuando se agota el número de reintentos configurados
  • Errores que se producen cuando un evento falla antes de que se pueda enrutar a su destino.
  • Errores que dan como resultado un código de error que se considera que no se puede volver a intentar. Por ejemplo, códigos de error distintos de los que se indican en los errores transitorios.

Puedes identificar manualmente los errores persistentes y gestionarlos de forma adecuada.

Reintentar errores transitorios

Eventarc Advanced usa un retraso de tiempo de espera exponencial para gestionar los errores que se pueden volver a intentar. La política de reintento predeterminada empieza con un retraso de un segundo y el retraso se duplica después de cada intento fallido (hasta un máximo de 60 segundos y cinco intentos).

Puedes cambiar la política de reintentos predeterminada mediante la consola Google Cloud o el comando gcloud eventarc pipelines update.

Ten en cuenta que el factor de espera predeterminado de 2 no se puede cambiar.

Consola

  1. En la Google Cloud consola, ve a la página Eventarc > Pipelines.

    Ir a Pipelines

  2. Haz clic en el nombre de la canalización.

  3. En la página Detalles de la canalización, haz clic en Editar.

  4. En la página Editar canalización, en la sección Política de reintentos, modifique los siguientes campos:

    • Número máximo de intentos: número de reintentos. El valor predeterminado es 5 intentos. Puede ser cualquier número real positivo. Si se asigna el valor 1, no se aplica ninguna política de reintento y solo se hace un intento para entregar un mensaje.
    • Retraso mínimo (segundos): el retraso inicial en segundos. El valor predeterminado es 1 segundo. Debe ser un valor entre 1 y 600.
    • Retraso máximo (segundos): el retraso máximo en segundos. El valor predeterminado es 60 segundos. Debe ser un valor entre 1 y 600.

    Puedes configurar un retroceso lineal asignando el mismo valor a los retrasos mínimo y máximo.

  5. Haz clic en Guardar.

gcloud

gcloud eventarc pipelines update PIPELINE_NAME \
    --min-retry-delay=MIN_DELAY \
    --max-retry-delay=MAX_DELAY \
    --max-retry-attempts=MAX_ATTEMPTS

Haz los cambios siguientes:

  • PIPELINE_NAME: el ID o el identificador completo del flujo de trabajo.
  • MIN_DELAY: el retraso inicial en segundos. El valor predeterminado es 1 segundo. Debe ser un valor entre 1 y 600.
  • MAX_DELAY: el retraso máximo en segundos. El valor predeterminado es 60 segundos. Debe ser un valor entre 1 y 600.
  • MAX_ATTEMPTS: número de reintentos. El valor predeterminado es 5 intentos. Puede ser cualquier número real positivo. Si se define como 1, no se aplica ninguna política de reintentos y solo se hace un intento para entregar un mensaje.

En el siguiente ejemplo se configura un retroceso lineal asignando el mismo valor a los retrasos mínimo y máximo:

gcloud eventarc pipelines update my-pipeline \
    --min-retry-delay=4 \
    --max-retry-delay=4 \
    --max-retry-attempts=5

Archivar mensajes para gestionar errores persistentes

Puedes escribir mensajes en una tabla de BigQuery a medida que se reciben. De esta forma, puedes identificar manualmente los errores persistentes y gestionarlos de forma adecuada.

A continuación, se ofrece una descripción general de los pasos necesarios para archivar los mensajes de eventos, identificar los errores persistentes y volver a intentar los eventos afectados.

  1. Crea un autobús. Configurar el bus correctamente; por ejemplo, para publicar eventos de fuentes de Google.
  2. Crea un tema de Pub/Sub. Este tema de Pub/Sub será el destino de tu canalización.
  3. Crea una suscripción de BigQuery para el tema de Pub/Sub. Una suscripción de BigQuery es un tipo de suscripción de exportación que escribe mensajes en una tabla de BigQuery a medida que se reciben. También puedes crear la tabla al crear la suscripción a BigQuery.
  4. Crea una canalización y un registro que dirija todos los mensajes recibidos por el bus (con --cel-match="true") al tema de Pub/Sub. Configura una política de reintentos para la canalización.

    Por ejemplo, los siguientes comandos crean una canalización y un registro:

    gcloud eventarc pipelines create my-archive-pipeline \
        --destinations=pubsub_topic='my-archive-topic' \
        --min-retry-delay=1 \
        --max-retry-delay=20 \
        --max-retry-attempts=6 \
        --location=us-central1
    
    gcloud eventarc enrollments create my-archive-enrollment \
        --cel-match="true" \
        --destination-pipeline=my-archive-pipeline \
        --message-bus=my-message-bus \
        --message-bus-project=my-google-cloud-project \
        --location=us-central1
    
  5. Dirige los registros de tu flujo de procesamiento a otro conjunto de datos de BigQuery.

    Ahora debería tener dos conjuntos de datos de BigQuery independientes: uno que almacene todos los mensajes recibidos por su bus avanzado de Eventarc y otro que almacene los registros de su canalización.

  6. Para identificar los mensajes que han fallado, usa una instrucción de consulta para combinar ambos conjuntos de datos de BigQuery en el campo message_uid.

  7. Una vez que haya identificado los mensajes fallidos, puede volver a publicarlos en su bus mediante la API Eventarc Publishing. Por ejemplo, puedes desplegar un servicio o un trabajo de Cloud Run para leer los mensajes de BigQuery y publicarlos directamente en el bus avanzado de Eventarc.

Hacer que los controladores de eventos sean idempotentes

Los controladores de eventos que se pueden volver a intentar deben ser idempotentes y seguir estas directrices generales:

  • Muchas APIs externas te permiten proporcionar una clave de idempotencia como parámetro. Si usas una API de este tipo, debes usar la fuente y el ID del evento como clave de idempotencia. Los productores deben asegurarse de que source + id sea único para cada evento distinto.
  • Además, puedes usar el atributo xgooglemessageuid de CloudEvents para proporcionar idempotencia. El valor de este atributo es el mismo que el del campo message_uid de los mensajes avanzados de Eventarc. Identifica de forma única la acción de publicar un evento. Por ejemplo, si el mismo evento se publica dos veces en un bus, cada evento tendrá un valor xgooglemessageuid diferente cuando se envíe a un controlador de eventos.
  • La idempotencia funciona bien con la entrega al menos una vez, ya que permite reintentar la operación de forma segura. Por lo tanto, una práctica recomendada general para escribir código fiable es combinar la idempotencia con los reintentos.
  • Asegúrate de que tu código sea idempotente internamente. Por ejemplo:
    • Asegúrate de que las mutaciones puedan producirse más de una vez sin cambiar el resultado.
    • Consulta el estado de la base de datos en una transacción antes de mutar el estado.
    • Asegúrate de que todos los efectos secundarios sean idempotentes.
  • Imponer una comprobación transaccional fuera de tu servicio, independientemente del código. Por ejemplo, persiste el estado en algún lugar registrando que ya se ha procesado un ID de evento determinado.
  • Gestiona las llamadas duplicadas fuera de banda. Por ejemplo, puedes tener un proceso de limpieza independiente que se ejecute después de las llamadas duplicadas.

Siguientes pasos