En esta página, se explica cómo recibir y confirmar mensajes con la función de procesamiento exactamente una vez de Pub/Sub, que te permite hacer un seguimiento de los mensajes y evitar el procesamiento duplicado. Cuando la función está habilitada, Pub/Sub proporciona la siguiente semántica:
Los suscriptores pueden determinar si los mensajes de acuse de recibo se entregaron correctamente.
No se realiza ninguna reenvío después de que se confirma correctamente el mensaje.
No se realiza ninguna reinstalación mientras un mensaje esté pendiente. Un mensaje se considera pendiente hasta que vence el plazo de confirmación de recepción o hasta que se confirma.
En el caso de varias publicaciones válidas, debido al vencimiento del plazo de confirmación o a la confirmación negativa que inicia el cliente, solo se puede usar el ID de confirmación más reciente para confirmar el mensaje. Todas las solicitudes con un ID de acuse de recibo anterior fallan.
Con la función de procesamiento exactamente una vez habilitada, los suscriptores pueden seguir estos lineamientos para garantizar que los mensajes se procesen una vez:
Confirma los mensajes dentro del plazo de confirmación.
Mantén la información sobre el progreso del procesamiento de un mensaje hasta que se confirme correctamente.
Usa la información sobre el progreso del procesamiento de un mensaje para evitar trabajos duplicados cuando falle un acuse de recibo.
Solo el tipo de suscripción de extracción admite la entrega de exactamente una vez, incluidos los suscriptores que usan la API de StreamingPull. Las suscripciones de envío y exportación no admiten la entrega exactamente una vez.
Pub/Sub admite la entrega de “exactamente una vez”, dentro de una región de nube, según un ID de mensaje único definido por Pub/Sub.
Versiones recomendadas de la biblioteca cliente
- Para obtener el mejor rendimiento, usa la versión más reciente de la biblioteca cliente, Python v2.13.6 o una posterior, Java v1.120.11 o una posterior, PHP v1.39.0 o una posterior, C# v3.2.0 o una posterior, C++ v2.1.0, Go v1.25.1 o una posterior, Node v3.2.0 o una posterior y Ruby v2.12.1 o una posterior.
Vuelve a publicar en lugar de duplicar
Es importante comprender la diferencia entre las reentregas esperadas y las inesperadas.
Una reinstalación puede ocurrir debido a la confirmación de recepción negativa de un mensaje que inicia el cliente o cuando el cliente no extiende el plazo de confirmación de recepción del mensaje antes de que venza. Las reentregas se consideran válidas y el sistema funciona según lo previsto.
Para solucionar problemas relacionados con las reenviaciones, consulta Cómo lidiar con duplicados.
Un duplicado se produce cuando se vuelve a enviar un mensaje después de una confirmación de recepción correcta o antes de que venza el plazo de confirmación.
Un mensaje reenviado conserva el mismo ID de mensaje entre los intentos de reenvío.
Las suscripciones con la entrega “exactamente una vez” habilitada no reciben entregas duplicadas.
Compatibilidad con la entrega “exactamente una vez” en las bibliotecas cliente
Las bibliotecas cliente compatibles tienen una interfaz para el acuse de recibo con respuesta (por ejemplo, Go). Puedes usar esta interfaz para verificar si la solicitud de acuse de recibo se realizó correctamente. Si la solicitud de acuse de recibo se realiza correctamente, se garantiza que los clientes no recibirán una nueva entrega. Si la solicitud de acuse de recibo falla, los clientes pueden esperar una nueva entrega.
Los clientes también pueden usar las bibliotecas cliente compatibles sin la interfaz de confirmación. Sin embargo, en esos casos, las fallas de confirmación pueden provocar que se vuelvan a entregar mensajes de forma silenciosa.
Las bibliotecas cliente admitidas tienen interfaces para establecer el tiempo mínimo de extensión del arrendamiento (por ejemplo, Go). Debes establecer el valor de la extensión mínima del arrendamiento en un número alto para evitar que venza cualquier acuse de recibo relacionado con la red. El valor máximo se establece en 600 segundos.
Los valores y el rango predeterminados de las variables relacionadas con la entrega exactamente una vez y los nombres de las variables pueden diferir entre las bibliotecas cliente. Por ejemplo, en la biblioteca cliente de Java, las siguientes variables controlan la entrega de exactamente una vez.
Variable | Descripción | Valor |
---|---|---|
setEnableExactlyOnceDelivery |
Habilita o inhabilita la entrega exactamente una vez. | verdadero o falso (predeterminado: falso) |
minDurationPerAckExtension |
Es el tiempo mínimo en segundos que se debe usar para extender el plazo de confirmación de la modificación. | Rango: De 0 a 600. Valor predeterminado: Ninguno |
maxDurationPerAckExtension |
Es el tiempo máximo en segundos que se usará para extender el plazo de confirmación de la modificación. | Rango: De 0 a 600. Valor predeterminado: Ninguno |
En el caso de la entrega de exactamente una vez, la solicitud modifyAckDeadline
o acknowledgment
a Pub/Sub falla cuando el ID de confirmación ya venció. En esos casos, el servicio considera que el ID de acuse de recibo vencido no es válido, ya que es posible que una entrega más reciente ya esté en curso. Esto se diseñó para la entrega de exactamente una vez. Luego, verás que las solicitudes acknowledgment
y ModifyAckDeadline
muestran una respuesta INVALID_ARGUMENT
. Cuando se inhabilita la entrega de exactamente una vez, estas solicitudes muestran OK
en los casos de IDs de acuse de recibo vencidos.
Para garantizar que las solicitudes de acknowledgment
y ModifyAckDeadline
tengan IDs de acuse de recibo válidos, considera establecer el valor de minDurationPerAckExtension
en un número alto.
Consideraciones regionales
La garantía de entrega exactamente una vez solo se aplica cuando los suscriptores se conectan al servicio en la misma región. Si tu aplicación de suscriptor se distribuye en varias regiones, es posible que se duplique la entrega de mensajes, incluso cuando se habilita la entrega exactamente una vez. Los publicadores pueden enviar mensajes a cualquier región y se mantiene la garantía de una sola vez.
Cuando ejecutas tu aplicación en Google Cloud, esta se conecta de forma predeterminada al extremo de Pub/Sub en la misma región. Por lo tanto, en general, ejecutar tu aplicación en una sola región de Google Cloud garantiza que estés interactuando con una sola región.
Cuando ejecutas tu aplicación de suscriptor fuera de Google Cloud o en varias regiones, puedes garantizar que te conectas a una sola región con un extremo de ubicación cuando configuras tu cliente de Pub/Sub. Todos los extremos de ubicación de Pub/Sub apuntan a regiones únicas. Para obtener más información sobre los extremos de ubicación, consulta Extremos de Pub/Sub. Para obtener una lista de todos los extremos de ubicación de Pub/Sub, consulta Lista de extremos de ubicación.
Crea suscripciones con entrega “exactamente una vez”
Puedes crear una suscripción con entrega exactamente una vez mediante la consola de Google Cloud, Google Cloud CLI, la biblioteca cliente o la API de Pub/Sub.
Suscripción de extracción
Console
Para crear una suscripción de extracción con entrega exactamente una vez, sigue estos pasos:
En la consola de Google Cloud, ve a la página Suscripciones.
Haz clic en Crear suscripción.
Ingresa el ID de suscripción.
Elige o crea un tema desde el menú desplegable.
La suscripción recibe mensajes del tema.
En la sección Entrega “exactamente una vez”, selecciona Habilitar entrega “exactamente una vez”.
Haz clic en Crear.
gcloud
Para crear una suscripción de extracción con entrega exactamente una vez, usa el comando
gcloud pubsub subscriptions create
con la marca --enable-exactly-once-delivery
:
gcloud pubsub subscriptions create SUBSCRIPTION_ID \ --topic=TOPIC_ID \ --enable-exactly-once-delivery
Reemplaza lo siguiente:
- SUBSCRIPTION_ID: Es el ID de la suscripción que se creará.
- TOPIC_ID: Es el ID del tema para adjuntar a la suscripción.
REST
Para crear una suscripción con entrega exactamente una vez, usa el método projects.subscriptions.create
.
PUT https://pubsub.googleapis.com/v1/projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID Authorization: Bearer $(gcloud auth print-access-token)
Reemplaza lo siguiente:
- PROJECT_ID: Es el ID del proyecto para crear la suscripción.
- SUBSCRIPTION_ID: Es el ID de la suscripción que se creará.
Para crear una suscripción de extracción con entrega exactamente una vez, especifícala en el cuerpo de la solicitud:
{ "topic": "projects/PROJECT_ID/topics/TOPIC_ID", "enableExactlyOnceDelivery": true, }
Reemplaza lo siguiente:
- PROJECT_ID: el ID del proyecto con el tema
- TOPIC_ID: Es el ID del tema para adjuntar a la suscripción.
C++
Antes de probar esta muestra, sigue las instrucciones de configuración de C++ en la guía de inicio rápido sobre el uso de bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Pub/Sub para C++.
C#
Antes de probar esta muestra, sigue las instrucciones de configuración de C# en la guía de inicio rápido sobre el uso de bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Pub/Sub para C#.
Go
Antes de probar esta muestra, sigue las instrucciones de configuración de Go en la guía de inicio rápido sobre el uso de bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Pub/Sub para Go.
Java
Antes de probar esta muestra, sigue las instrucciones de configuración de Java en la guía de inicio rápido sobre el uso de bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Pub/Sub para Java.
Python
Antes de probar esta muestra, sigue las instrucciones de configuración de Python en la guía de inicio rápido sobre el uso de bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Pub/Sub para Python.
Node.js
Antes de probar esta muestra, sigue las instrucciones de configuración de Node.js en la guía de inicio rápido sobre el uso de bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Pub/Sub para Node.js.
Node.js
Antes de probar esta muestra, sigue las instrucciones de configuración de Node.js en la guía de inicio rápido sobre el uso de bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Pub/Sub para Node.js.
Ruby
Antes de probar esta muestra, sigue las instrucciones de configuración de Ruby en la guía de inicio rápido sobre el uso de bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Pub/Sub para Ruby.
PHP
Antes de probar esta muestra, sigue las instrucciones de configuración de PHP en la guía de inicio rápido sobre el uso de bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Pub/Sub para PHP.
Suscríbete con entrega de mensajes exactamente una vez
A continuación, se incluyen algunas muestras de código para suscribirse con la entrega de exactamente una vez con la biblioteca cliente.
Suscripción de extracción
Go
Antes de probar esta muestra, sigue las instrucciones de configuración de Go que encontrarás en la guía de inicio rápido de Pub/Sub con bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Go de Pub/Sub.
Para autenticarte en Pub/Sub, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.
Java
Antes de probar esta muestra, sigue las instrucciones de configuración de Java que encontrarás en la guía de inicio rápido de Pub/Sub con bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Java de Pub/Sub.
Para autenticarte en Pub/Sub, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.
Node.js
Antes de probar esta muestra, sigue las instrucciones de configuración de Node.js que encontrarás en la guía de inicio rápido de Pub/Sub con bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Node.js de Pub/Sub.
Para autenticarte en Pub/Sub, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.
PHP
Antes de probar esta muestra, sigue las instrucciones de configuración de PHP que encontrarás en la guía de inicio rápido de Pub/Sub con bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de PHP de Pub/Sub.
Para autenticarte en Pub/Sub, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.
Python
Antes de probar esta muestra, sigue las instrucciones de configuración de Python que encontrarás en la guía de inicio rápido de Pub/Sub con bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Python de Pub/Sub.
Para autenticarte en Pub/Sub, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.
Ruby
Antes de probar esta muestra, sigue las instrucciones de configuración de Ruby que encontrarás en la guía de inicio rápido de Pub/Sub con bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Ruby de Pub/Sub.
Para autenticarte en Pub/Sub, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.
C++
Antes de probar esta muestra, sigue las instrucciones de configuración de C++ que encontrarás en la guía de inicio rápido de Pub/Sub con bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de C++ de Pub/Sub.
Para autenticarte en Pub/Sub, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.
C#
Antes de probar esta muestra, sigue las instrucciones de configuración de C# que encontrarás en la guía de inicio rápido de Pub/Sub con bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de C# de Pub/Sub.
Para autenticarte en Pub/Sub, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.
Node.js (TypeScript)
Antes de probar esta muestra, sigue las instrucciones de configuración de Node.js en la guía de inicio rápido de Pub/Sub mediante bibliotecas cliente. Si quieres obtener más información, consulta la documentación de referencia de la API de Pub/Sub para Node.js.
Para autenticarte en Pub/Sub, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para un entorno de desarrollo local.
Supervisa las suscripciones de entrega “exactamente una vez”
La métrica subscription/exactly_once_warning_count
registra la cantidad de eventos que pueden generar posibles reenvíos (válidos o duplicados). Esta métrica cuenta las veces que Pub/Sub no puede procesar solicitudes asociadas con IDs de acuse de recibo (solicitud ModifyAckDeadline
o acknowledgment
). Los motivos de la falla pueden ser del servidor o del cliente. Por ejemplo, si la capa de persistencia que se usa para mantener la información de entrega de exactamente una vez no está disponible, sería un evento basado en el servidor. Si el cliente intenta confirmar un mensaje con un ID de confirmación no válido, se trata de un evento basado en el cliente.
Comprende la métrica
subscription/exactly_once_warning_count
captura eventos que pueden o no generar reenvío reales y pueden ser ruidosos según el comportamiento del cliente. Por ejemplo, las solicitudes repetidas de acknowledgment
o ModifyAckDeadline
con IDs de acuse de recibo no válidos incrementan la métrica de forma reiterada.
Las siguientes métricas también son útiles para comprender el comportamiento de los clientes:
La métrica
subscription/expired_ack_deadlines_count
muestra la cantidad de vencimientos de IDs de acuse de recibo. El vencimiento de los IDs de acuse de recibo puede provocar fallas en las solicitudes deModifyAckDeadline
yacknowledgment
.La métrica
service.serviceruntime.googleapis.com/api/request_count
se puede usar para capturar fallas de solicitudes deModifyAckDeadline
oacknowledgment
en los casos en que las solicitudes llegan a Google Cloud, pero no a Pub/Sub. Hay fallas que esta métrica no capturará, por ejemplo, cuando los clientes se desconectan de Google Cloud.
En la mayoría de los casos de eventos de error que se pueden reintentar, las bibliotecas cliente compatibles reintentan la solicitud automáticamente.
Cuotas
Las suscripciones a la entrega exactamente una vez están sujetas a requisitos de cuota adicionales. Estas cuotas se aplican en los siguientes casos:
- Cantidad de mensajes consumidos de las suscripciones con la entrega exactamente una vez habilitada por región.
- Cantidad de mensajes confirmados o cuya fecha límite se extiende cuando se usan suscripciones con entrega de exactamente una vez habilitada por región.
Para obtener más información sobre estas cuotas, consulta la tabla en el tema Cuotas.
Entrega “exactamente una vez” y suscripciones ordenadas
Pub/Sub admite la entrega exactamente una vez con la entrega ordenada.
Cuando se usa el ordenamiento con la entrega exactamente una vez, Pub/Sub espera que los acuses de recibo estén en orden. Si los acuses de recibo están fuera de orden, el servicio falla las solicitudes con errores temporales. Si el plazo de confirmación vence antes de que se reciba una confirmación en orden para la entrega, el cliente recibirá una reimpresión del mensaje. Debido a esto, cuando usas el ordenamiento con entrega de exactamente una vez, la capacidad de procesamiento del cliente se limita a un orden de mil mensajes por segundo.
Entrega “exactamente una vez” y suscripciones push
Pub/Sub admite la entrega exactamente una vez solo con suscripciones de extracción.
Los clientes que consumen mensajes de las suscripciones push confirman los mensajes respondiendo a las solicitudes de envío con una respuesta correcta. Sin embargo, los clientes no saben si la suscripción a Pub/Sub recibió la respuesta y la procesó. Esto es diferente de las suscripciones de extracción, en las que los clientes inician solicitudes de acuse de recibo y la suscripción a Pub/Sub responde si la solicitud se procesó correctamente. Por este motivo, la semántica de entrega de exactamente una vez no se alinea bien con las suscripciones push.
Qué debes saber
Si no se especifica la fecha límite de confirmación en el momento de CreateSubscription, las suscripciones habilitadas para la entrega exactamente una vez tendrán una fecha límite de confirmación predeterminada de 60 segundos.
Los plazos de confirmación predeterminados más largos son beneficiosos para evitar la reenvío causado por eventos de red. Las bibliotecas cliente compatibles no usan el plazo de confirmación de suscripción predeterminado.
Las suscripciones con entrega exactamente una vez tienen una latencia de publicación-suscripción mucho más alta en comparación con las suscripciones normales.
Si necesitas una capacidad de procesamiento alta, tus clientes de entrega exactamente una vez también deben usar la extracción de transmisión.
Es posible que una suscripción reciba varias copias del mismo mensaje debido a duplicados del lado de la publicación, incluso con la entrega exactamente una vez habilitada. Los duplicados del lado de la publicación pueden deberse a varios reintentos de publicación únicos del cliente de publicación o del servicio de Pub/Sub. Si el cliente de publicación realiza varias publicaciones únicas en los reintentos, se producirán nuevas publicaciones con diferentes IDs de mensaje. Si el servicio de Pub/Sub realiza varias publicaciones únicas para responder a una solicitud de publicación del cliente, se producirán reenvíos con los mismos IDs de mensaje.
Puedes volver a intentar los errores en
subscription/exactly_once_warning_count
, y las bibliotecas cliente compatibles los reintentan automáticamente. Sin embargo, no se pueden volver a intentar los errores relacionados con los IDs de acuse de recibo no válidos.