Un evento se puede rechazar por varios motivos. Por ejemplo, es posible que el servicio del receptor de eventos no esté disponible temporalmente debido a una interrupción, que el servicio encuentre un error cuando procese un evento o que se agoten los recursos del servicio. Los errores transitorios como este se pueden volver a intentar.
Un evento también puede no entregarse al receptor de eventos. Por ejemplo, es posible que el evento no coincida con el esquema esperado que se configuró, o que la mediación del evento falle antes de que el mensaje del evento se pueda enrutar a su destino final. Estos casos generan errores persistentes.
Errores transitorios
Eventarc Advanced te brinda la capacidad de controlar errores transitorios. Estos errores transitorios se pueden volver a intentar y, entre ellos, se 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 lo siguiente:
- Errores que se producen cuando se agota la cantidad de reintentos configurados
- Son errores que se producen cuando un evento falla antes de que se pueda enrutar a su destino.
- Errores que generan un código de error que se considera que no se puede reintentar (por ejemplo, códigos de error distintos de los que se indican para los errores transitorios)
Puedes identificar de forma manual los errores persistentes y controlarlos de forma adecuada.
Cómo reintentar errores transitorios
Eventarc Advanced usa un retraso con retirada exponencial para manejar errores que se pueden reintentar. La política de reintento predeterminada comienza con una demora de un segundo, y la demora se duplica después de cada intento fallido (hasta un máximo de 60 segundos y cinco intentos).
Puedes cambiar la política de reintento predeterminada con la consola de Google Cloud o el comando gcloud beta eventarc pipelines update
.
Ten en cuenta que no se puede cambiar el factor de tiempo de espera predeterminado de 2
.
Console
En la consola de Google Cloud, ve a la página Eventarc > Canales.
Haz clic en el nombre de la canalización.
En la página Detalles de la canalización, haz clic en Editar.
En la página Editar canalización, en la sección Política de reintento, modifica los siguientes campos:
- Max attempts: Es la cantidad de reintentos. El valor predeterminado es
5
. Puede ser cualquier número real positivo. Si se establece en1
, no se aplica ninguna política de reintentos y solo se realiza un intento para entregar un mensaje. - Retraso mín. (segundos): Es el retraso inicial en segundos. El valor predeterminado es de
1
segundos. Debe estar entre1
y600
. - Retraso máx. (segundos): Es el retraso máximo en segundos. El valor predeterminado es de
60
segundos. Debe estar entre1
y600
.
Para configurar una disminución lineal, establece las demoras mínimas y máximas en el mismo valor.
- Max attempts: Es la cantidad de reintentos. El valor predeterminado es
Haz clic en Guardar.
gcloud
gcloud beta eventarc pipelines update PIPELINE_NAME \
--min-retry-delay=MIN_DELAY \
--max-retry-delay=MAX_DELAY \
--max-retry-attempts=MAX_ATTEMPTS
Reemplaza lo siguiente:
PIPELINE_NAME
: El ID o el identificador completamente calificado de la canalización.MIN_DELAY
: Es el retraso inicial en segundos. El valor predeterminado es de1
segundos. Debe estar entre1
y600
.MAX_DELAY
: Es la demora máxima en segundos. El valor predeterminado es de60
segundos. Debe estar entre1
y600
.MAX_ATTEMPTS
: Es la cantidad de reintentos. El valor predeterminado es5
. Puede ser cualquier número real positivo. Si se establece en1
, no se aplica ninguna política de reintentos y solo se realiza un intento para entregar un mensaje.
En el siguiente ejemplo, se configura una retirada lineal estableciendo los retrasos mínimo y máximo en el mismo valor:
gcloud beta eventarc pipelines update my-pipeline \
--min-retry-delay=4 \
--max-retry-delay=4 \
--max-retry-attempts=5
Cómo archivar mensajes para controlar errores persistentes
Puedes escribir mensajes en una tabla de BigQuery a medida que se reciben. Esto te permite identificar manualmente los errores persistentes y controlarlos de forma adecuada.
A continuación, se proporciona una descripción general de los pasos necesarios para archivar los mensajes de tus eventos, identificar los errores persistentes y volver a intentar los eventos afectados.
- Crea un bus. Configura el bus de manera adecuada, por ejemplo, para publicar eventos de fuentes de Google.
- Crea un tema de Pub/Sub. Este tema de Pub/Sub será el destino de tu canalización.
- Crea una suscripción a BigQuery para el tema de Pub/Sub. Una suscripción a BigQuery es un tipo de suscripción de exportación que escribe los mensajes en una tabla de BigQuery existente a medida que se reciben. Como alternativa, puedes crear la tabla cuando crees la suscripción a BigQuery.
Crea una canalización y una inscripción que enrute cada mensaje que recibe 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 una inscripción:
gcloud beta eventarc pipelines create my-archive-pipeline \ --destinations=pubsub_topic='my-archive-topic',network_attachment='my-network-attachment' \ --min-retry-delay=1 \ --max-retry-delay=20 \ --max-retry-attempts=6 \ --location=us-central1
gcloud beta 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
Enruta los registros de tu canalización a otro conjunto de datos de BigQuery.
Ahora deberías tener dos conjuntos de datos de BigQuery separados: uno que almacena cada mensaje que recibe tu bus avanzado de Eventarc y otro que almacena los registros de tu canalización.
Para identificar los mensajes que fallaron, usa una sentencia de consulta para unir ambos conjuntos de datos de BigQuery en el campo
message_uid
.Después de identificar los mensajes que fallaron, puedes volver a publicarlos en el bus con la API de Eventarc Publishing. Por ejemplo, puedes implementar un servicio o trabajo de Cloud Run para leer los mensajes de BigQuery y publicarlos directamente en el bus avanzado de Eventarc.
Haz que los controladores de eventos sean idempotentes
Los controladores de eventos que se pueden reintentar deben ser idempotentes con los siguientes lineamientos 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 la clave de idempotencia. (Los productores deben asegurarse de que source + id sea único para cada evento distinto).
- Además, puedes usar un atributo de CloudEvents,
xgooglemessageuid
, para proporcionar idempotencia. El valor de este atributo es el mismo que el campomessage_uid
en 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 valorxgooglemessageuid
diferente cuando se envíe a un controlador de eventos. - La idempotencia funciona bien con la entrega "al menos una vez", ya que permite que los reintentos sean seguros. Por lo tanto, una recomendación general para escribir un código confiable es combinar la idempotencia con los intentos reiterados.
- Asegúrate de que tu código sea idempotente de forma interna. Por ejemplo:
- Asegúrate de que puedan ocurrir mutaciones más de una vez sin que cambie 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 en sí.
- Debes imponer una verificación transaccional fuera del servicio, sin importar el código. Por ejemplo, conserva el estado en algún lugar que registre si ya se procesó un ID de evento determinado.
- Administra las llamadas duplicadas fuera de banda. Por ejemplo, implementa un proceso de limpieza independiente que borre las llamadas duplicadas.