Un evento se puede rechazar por varios motivos. Por ejemplo, es posible que el servicio receptor de eventos no esté disponible temporalmente debido a una interrupción, que el servicio encuentre un error cuando procesa un evento o que se agoten los recursos del servicio. Se pueden reintentar los errores transitorios como este.
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 está configurado 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 reintentar y, además, incluyen aquellos con 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
- Errores que se producen cuando falla un evento 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 enumeran para los errores transitorios
Puedes identificar errores persistentes de forma manual y controlarlos de manera adecuada.
Reintenta errores transitorios
Eventarc Advanced usa un retraso con retirada exponencial para manejar errores que se pueden reintentar. La política de reintentos predeterminada comienza 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 con la Google Cloud consola de o el
gcloud eventarc pipelines update
comando.
Ten en cuenta que no se puede cambiar el factor de retirada predeterminado de 2.
Console
En la Google Cloud consola de, ve a la página Eventarc > Canalizaciones.
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 reintentos, modifica los siguientes campos:
- Intentos máximos: Es la cantidad de intentos de entrega. El valor predeterminado es
5intentos. Puede ser cualquier número entero 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ínimo (segundos): Es el retraso inicial en segundos. El valor predeterminado es
1segundo. Debe estar entre1y600. - Retraso máximo (segundos): Es el retraso máximo en segundos. El valor predeterminado es
60segundos. Debe estar entre1y600.
Puedes configurar una retirada lineal si estableces los retrasos mínimo y máximo en el mismo valor.
- Intentos máximos: Es la cantidad de intentos de entrega. El valor predeterminado es
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
Reemplaza lo siguiente:
PIPELINE_NAME: Es el ID o el identificador completamente calificado de la canalización.MIN_DELAY: Es el retraso inicial en segundos. El valor predeterminado es1segundo. Debe estar entre1y600.MAX_DELAY: Es el retraso máximo en segundos. El valor predeterminado es60segundos. Debe estar entre1y600.MAX_ATTEMPTS: Es la cantidad de intentos de entrega. El valor predeterminado es5intentos. Puede ser cualquier número entero 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 si se establecen los retrasos mínimo y máximo en el mismo valor:
gcloud eventarc pipelines update my-pipeline \
--min-retry-delay=4 \
--max-retry-delay=4 \
--max-retry-attempts=5
Archiva mensajes para controlar errores persistentes
Puedes escribir mensajes en una tabla de BigQuery a medida que se reciben. Esto te permite identificar errores persistentes de forma manual y controlarlos de manera adecuada.
A continuación, se proporciona una descripción general de los pasos necesarios para archivar los mensajes de eventos, identificar errores persistentes y reintentar los eventos afectados.
- Crea un bus. Configura el bus de forma 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 creas la suscripción a BigQuery.
Crea una canalización y una inscripción que enrute cada mensaje que reciba 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 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-central1gcloud 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-central1Enruta 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 de Eventarc Advanced y otro que almacena los registros de tu canalización.
Para identificar los mensajes que fallaron, usa una instrucción de consulta para unir ambos conjuntos de datos de BigQuery en el campo
message_uid.Después de identificar los mensajes fallidos, puedes volver a publicarlos en tu bus con la API de publicación de Eventarc mediante la API de publicación de Eventarc. Por ejemplo, puedes implementar un servicio o trabajo de Cloud Run para leer los mensajes de BigQuery y publicarlos directamente en el bus de Eventarc Advanced.
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 la fuente + el ID sean únicos 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_uiden los mensajes de Eventarc Advanced. 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 valorxgooglemessageuiddiferente 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.