En este documento, se proporcionan algunas sugerencias comunes para solucionar problemas relacionados con las suscripciones de extracción de Pub/Sub. Obtén más información sobre las suscripciones de extracción en la guía para suscriptores de extracción.
Para supervisar de forma eficaz tu suscripción a Pub/Sub, se recomienda que primero consultes la puntuación de estado de la latencia de entrega (subscription/delivery_latency_health_score) para verificar qué factores pueden contribuir a una latencia inesperada o mayor.
La antigüedad del mensaje sin confirmación más antiguo sigue aumentando
La métrica oldest_unacked_message_age es fundamental para supervisar el estado de las suscripciones de Pub/Sub. Mide la antigüedad, en segundos, del mensaje más antiguo en la lista de tareas pendientes de una suscripción que aún no confirmó (acked) un suscriptor. Esta métrica ofrece información valiosa sobre posibles retrasos o cuellos de botella en el procesamiento.
Supervisar la lista de mensajes pendientes garantiza un procesamiento de mensajes oportuno y eficiente. Si haces un seguimiento de la antigüedad del mensaje sin confirmar más antiguo, puedes identificar de forma proactiva las situaciones en las que los consumidores se están quedando atrás. Esta práctica permite una intervención temprana para abordar posibles problemas relacionados con la degradación del rendimiento.
Estos son algunos de los problemas comunes de la lista de tareas pendientes que puedes investigar:
Problemas de configuración del cliente
Cuando las métricas oldest_unacked_message_age y num_undelivered_messages aumentan de forma simultánea, podría significar que los suscriptores no están al día con el volumen de mensajes. En esta situación, enfoca tu investigación en los componentes del suscriptor:
Estado del cliente: Analiza el uso de recursos en las máquinas que alojan clientes suscriptores, como la CPU, la memoria y el ancho de banda de la red. Busca puntos de presión que puedan impedir la eficiencia del procesamiento.
Código de cliente: Revisa los cambios recientes en el código y examina los registros de errores. Los errores o las ineficiencias en el código del suscriptor pueden afectar significativamente las tasas de procesamiento de mensajes. Ten en cuenta que podría haber problemas en mensajes específicos. Por ejemplo, es posible que varios mensajes necesiten acceder a la misma fila de una base de datos de forma simultánea. Este comportamiento puede generar contención y una latencia alta.
Limitaciones de cuota: Verifica que no hayas excedido ninguna cuota o limitación de Pub/Sub impuesta por tu servicio de hosting. Si los suscriptores se alojan en Google Cloud, revisa las cuotas de recursos de Compute Engine o GKE para evitar posibles cuellos de botella.
El suscriptor confirmó negativamente los mensajes
Cuando un suscriptor confirma de forma negativa (nack) un mensaje, le indica a Pub/Sub que el mensaje no se pudo procesar correctamente. Luego, Pub/Sub intenta volver a entregar el mismo mensaje. Las nacks repetidas para un mensaje generan duplicados y, posiblemente, un gran retraso en la entrega de mensajes.
Ten en cuenta que enviar un nack para un mensaje no garantizará que la próxima extracción recupere un mensaje diferente. La política de reintento de entrega de Pub/Sub podría seguir reintentando la entrega de los mensajes con confirmación negativa antes de los nuevos. Por lo tanto, no confíes en los nacks como un método para filtrar o omitir mensajes específicos. En su lugar, establece una política de reintentos, preferiblemente una retirada exponencial, como una forma de retirar los mensajes individuales que es probable que se procesen más adelante, pero que necesitan un poco más de tiempo antes de volver a entregarse.
Si necesitas omitir ciertos mensajes de forma intencional, el enfoque recomendado es confirmarlos, incluso si no los procesarás. Esto los quita de la suscripción, evita reintentos de entrega innecesarios y reduce el consumo de recursos. Dejar mensajes sin confirmar, ya sea de forma intencional o no, genera problemas de tareas pendientes y entregas duplicadas.
Latencia de entrega alta
La latencia de entrega en Pub/Sub es el tiempo que tarda un mensaje de un publicador en llegar a un suscriptor. En las siguientes secciones, se describen algunas de las posibles causas de una latencia de entrega alta.
No hay suficientes suscriptores
En el caso de los clientes que usan StreamingPull, para lograr una latencia baja de forma constante, mantén varias conexiones de StreamingPull abiertas a tu suscripción. Sin conexiones de suscriptores activas, Pub/Sub no puede entregar mensajes con rapidez. Un solo flujo podría ser un punto único de fallo, lo que aumenta el riesgo de retrasos. La métrica subscription/open_streaming_pulls proporciona visibilidad de la cantidad de conexiones de transmisión activas. Usa esta opción para asegurarte de tener siempre suficientes transmisiones para controlar los mensajes entrantes.
En el caso de los clientes que usan la extracción unaria, para lograr una latencia baja de forma constante, mantén varias solicitudes de extracción pendientes para tu suscripción. Las solicitudes poco frecuentes podrían acumular mensajes en la lista de tareas pendientes y aumentar la latencia. Este enfoque ayuda a minimizar las brechas en la conectividad y mejorar la latencia de entrega.
Se recomienda la biblioteca cliente de alto nivel para los casos en los que se requiere una alta capacidad de procesamiento y una baja latencia con una sobrecarga operativa y un costo de procesamiento mínimos. De forma predeterminada, la biblioteca cliente de alto nivel usa la API de StreamingPull, ya que suele ser una mejor opción para minimizar la latencia. Las bibliotecas cliente de alto nivel contienen funciones y clases precompiladas que controlan las llamadas a la API subyacentes para la autenticación, la optimización de la capacidad de procesamiento y la latencia, el formato de los mensajes y otras funciones.
Problemas de configuración del cliente
Consulta Problemas de configuración del cliente.
Tareas pendientes
Ten en cuenta que una acumulación de mensajes sin confirmar en una suscripción de Pub/Sub aumenta de forma inherente la latencia de extremo a extremo, ya que los suscriptores no procesan los mensajes de inmediato.
Claves de ordenamiento y entrega “exactamente una vez”
Las claves de ordenamiento y la entrega de tipo “exactamente una vez” son funciones valiosas, pero requieren una coordinación adicional dentro de Pub/Sub para garantizar la entrega correcta. Esta coordinación puede reducir la disponibilidad y aumentar la latencia. Si bien la diferencia es mínima en el estado estable, cualquier paso de coordinación necesario podría generar aumentos temporales en la latencia o una mayor tasa de errores. Si el ordenamiento está habilitado, los mensajes con una clave de ordenamiento no se pueden entregar hasta que se confirmen los anteriores con la misma clave de ordenamiento.
Considera si el orden de los mensajes o la entrega exactamente una vez son absolutamente esenciales para tu aplicación. Si la baja latencia es tu máxima prioridad, minimizar el uso de estas funciones podría ayudar a reducir las demoras en el procesamiento de mensajes.
Aumento del tamaño de los mensajes
Un aumento repentino en el tamaño del mensaje podría aumentar el tiempo de transferencia entre Pub/Sub y tu cliente, y ralentizar el tiempo de procesamiento de los mensajes en el cliente.
Si observas un aumento en la latencia de entrega, puedes verificar los tamaños de los mensajes con la métrica topic/message_sizes, agrupando por topic_id. Correlaciona los aumentos repentinos en el tamaño de los mensajes con los problemas de rendimiento observados.
Faltan mensajes
Si sospechas que los mensajes no se entregan correctamente a tu suscriptor, uno de los siguientes motivos podría ser el factor contribuyente.
Distribución de mensajes en suscripciones de Pub/Sub con varios consumidores
En Pub/Sub, los mensajes se pueden distribuir de forma desigual entre los consumidores de la misma suscripción. Pub/Sub balancea las cargas de los mensajes entre todos los clientes activos, pero el objetivo principal es maximizar la capacidad de procesamiento general de los mensajes y minimizar la lista de tareas pendientes, en lugar de garantizar una distribución perfectamente uniforme. El sistema dirige de forma dinámica más mensajes a los consumidores que demuestran una mayor capacidad, es decir, aquellos que confirman la recepción de los mensajes con rapidez y no están limitados por su configuración de control de flujo. Los consumidores que procesan mensajes a diferentes velocidades o que operan en diferentes condiciones (p.ej., disponibilidad de recursos, latencia de red) probablemente manejarán diferentes volúmenes de mensajes. Por lo general, los consumidores más rápidos y con mayor capacidad de respuesta recibirán y procesarán una mayor parte de la carga de mensajes.
Este método de distribución entre varios consumidores implica que el orden en que se reciben y procesan los mensajes puede variar. Por lo tanto, a menos que el ordenamiento de mensajes esté habilitado para la suscripción y los publicadores incluyan claves de ordenamiento, no se garantiza que los consumidores procesen los mensajes en el orden en que se publicaron.
Ten en cuenta que es posible que ya haya mensajes pendientes para los clientes y que una acumulación de mensajes sin confirmar no significa necesariamente que recibirás esos mensajes en tu próxima solicitud de extracción. Ten en cuenta que un consumidor puede ser alguien que use la extracción en la consola de Google Cloud o Google Cloud CLI, o que ejecute un suscriptor personalizado de forma local para verificar los mensajes.
En el caso de los clientes de extracción unaria, es posible que observes que algunas solicitudes de extracción no devuelven mensajes. Como se mencionó en la sección No hay suficientes suscriptores, se recomienda mantener varias solicitudes de extracción pendientes, ya que algunas podrían devolver menos mensajes que la cantidad máxima configurada, o incluso cero mensajes, aunque exista una lista de tareas pendientes. Esto se debe a que otros consumidores podrían tener arrendamientos de los mensajes disponibles.
Si un consumidor no confirma la recepción de un mensaje dentro del plazo de confirmación o si confirma negativamente (NACK) el mensaje, Pub/Sub intentará volver a entregarlo. Este reintento de entrega se puede realizar a cualquier consumidor activo de la suscripción, no necesariamente al que lo recibió inicialmente. Por lo tanto, un ID de mensaje en particular se puede entregar a varios consumidores diferentes conectados a la suscripción durante su ciclo de vida, y estos pueden intentar procesarlo, hasta que uno de ellos lo confirme correctamente.
Si sospechas que hay comportamientos inesperados en la distribución de mensajes, investiga si hay varios consumidores conectados simultáneamente a la suscripción y, luego, inspecciona sus métricas de rendimiento y configuraciones individuales.
Filtra en la suscripción
Verifica si la suscripción tiene un filtro adjunto. Si es así, solo recibirás los mensajes que coincidan con el filtro. El servicio de Pub/Sub confirma automáticamente los mensajes que no coinciden con el filtro. Considera cómo afectan los filtros a las métricas de tareas pendientes.
Usa la opción returnImmediately
Si tu cliente usa la extracción unaria, verifica si el campo returnImmediately está configurado como verdadero. Este es un campo obsoleto que le indica al servicio de Pub/Sub que responda a la solicitud de extracción de inmediato, incluso si se devuelve sin mensajes. Esto puede provocar que las solicitudes de extracción se devuelvan con 0 mensajes, incluso cuando hay una lista de tareas pendientes.
Problemas de configuración del cliente
Si usas la biblioteca cliente de Java y, además, inicializas tu suscriptor
con un canal de gRPC personalizado con el
método setChannelProvider(),
debes asegurarte de que el parámetro de configuración maxInboundMessageSize sea de al menos
20 MB (que coincida con el valor predeterminado
de la biblioteca)
cuando compiles tu TransportChannelProvider. Cuando este valor es inferior a
10 MB, los mensajes que superen los maxInboundMessageSize no se recibirán
correctamente. Algunos métodos comunes para establecer este parámetro de configuración son
InstantiatingGrpcChannelProvider.Builder.setMaxInboundMessageSize()
y
ManagedChannelBuilder.maxInboundMessageSize().
Cómo lidiar con los duplicados
Un suscriptor puede recibir mensajes duplicados en los siguientes casos:
Reintento de entrega. Un cliente confirmó de forma negativa un mensaje o venció la fecha límite de confirmación. Se espera que esto suceda.
Entrega duplicada. Un mensaje se vuelve a enviar después de una confirmación correcta o antes de que venza el plazo de confirmación. Las suscripciones con la entrega única exacta habilitada no reciben entregas duplicadas.
Mensajes duplicados del publicador El publicador envía un mensaje dos veces debido a la lógica de la aplicación del publicador. El servicio de Pub/Sub los trata como mensajes de Pub/Sub distintos y les asigna IDs de mensaje únicos.
Si los IDs de los mensajes son iguales, significa que Pub/Sub volvió a enviar o entregar el mensaje. Si los IDs de mensaje son diferentes, significa que la duplicación se produjo antes, en el publicador.
Plazos de confirmación vencidos
La duplicación de mensajes en Pub/Sub suele ocurrir cuando los suscriptores no pueden confirmar la recepción de los mensajes dentro del plazo de confirmación. Esto hace que los mensajes se vuelvan a entregar, lo que crea la impresión de que hay duplicados. Puedes medir la frecuencia con la que los suscriptores no cumplen con la fecha límite de confirmación con la métrica subscription/expired_ack_deadlines_count. Obtén más información para supervisar el vencimiento del plazo de confirmación.
Para reducir la tasa de duplicación, extiende los plazos de los mensajes.
- Las bibliotecas cliente controlan la extensión de la fecha límite automáticamente, pero hay límites predeterminados en la fecha límite máxima de extensión que puedes configurar.
- Si estás compilando tu propia biblioteca cliente, usa el método
modifyAckDeadlinepara extender la fecha límite de confirmación.
Si los mensajes se extraen en el suscriptor más rápido de lo que se pueden procesar y confirmar, es posible que algunos mensajes venzan y requieran extensiones de plazo. Sin embargo, si el suscriptor sigue sobrecargado, las extensiones de plazo repetidas fallarán con el tiempo. En el peor de los casos, esto puede provocar que un suscriptor se desborde con duplicados, lo que agrava la acumulación. Los duplicados que vencen generan duplicados nuevos.
Para evitar sobrecargar al suscriptor, reduce la cantidad de mensajes que este extrae a la vez. De esta manera, el suscriptor tiene menos mensajes para procesar dentro de la fecha límite. Vencen menos mensajes y se reintentan menos entregas.
Para reducir la cantidad de mensajes que el suscriptor extrae a la vez, debes reducir el parámetro de configuración de la cantidad máxima de mensajes pendientes en la configuración del control de flujo del suscriptor. No existe un valor único para todos los casos, por lo que debes ajustar el límite máximo de mensajes pendientes según tu capacidad de procesamiento y la capacidad de los suscriptores. Ten en cuenta que cada aplicación procesa los mensajes de manera diferente y tarda un tiempo distinto en confirmar la recepción de un mensaje.
Fuerza los reintentos
Para forzar a Pub/Sub a que vuelva a intentar enviar un mensaje, envía una solicitud nack. Si no usas las bibliotecas cliente de alto nivel, envía una solicitud modifyAckDeadline con un ackDeadlineSeconds establecido en 0.
Claves de ordenamiento
Cuando Pub/Sub vuelve a entregar un mensaje con una clave de ordenamiento, también vuelve a entregar todos los mensajes posteriores con la misma clave de ordenamiento, incluso si se confirmó su recepción con anterioridad. Esto se hace para preservar el orden de la secuencia. Sin embargo, no hay una garantía estricta de que los mensajes dependientes solo se envíen después de que se confirmen correctamente los mensajes anteriores de la secuencia.
El suscriptor envía nacks para los mensajes
Consulta El suscriptor envía nacks para los mensajes.
Operaciones de búsqueda
Cuando realizas una operación de búsqueda en una marca de tiempo o una instantánea, Pub/Sub vuelve a entregar los mensajes que se publicaron después de la marca de tiempo o que se incluyeron en la instantánea. Este reintento de entrega es un comportamiento esperado y se produce incluso si la entrega exactamente una vez está habilitada en la suscripción. Para obtener más información, consulta Busca con la entrega de una sola vez.
Anulación de duplicación downstream
Los suscriptores y otros sistemas downstream podrían anular la duplicación de mensajes. Por ejemplo, Dataflow admite la entrega exactamente una vez. Si ves que aparecen mensajes duplicados de forma inesperada, la causa podría estar en el suscriptor y no en Pub/Sub.
Soluciona problemas de una suscripción de StreamingPull
Relación entre la métrica de latencia de la solicitud y la latencia de entrega de extremo a extremo
En el caso de StreamingPull, la métrica serviceruntime.googleapis.com/api/request_latencies representa el tiempo durante el cual la transmisión está abierta. La métrica no es útil para determinar la latencia de entrega de extremo a extremo.
En lugar de usar la métrica de latencia de solicitudes, usa la puntuación de estado de la latencia de entrega para verificar qué factores contribuyen a un aumento de la latencia de entrega de extremo a extremo.
Las conexiones de StreamingPull se cierran con un estado distinto de OK
Las transmisiones de StreamingPull siempre se cierran con un estado que no es correcto. A diferencia de un estado de error para las RPC unarias, este estado para StreamingPull solo indica que la transmisión está desconectada. Las solicitudes no fallan. Por lo tanto, si bien la API de StreamingPull puede tener una tasa de error sorprendente del 100%, este comportamiento es por diseño.
Dado que las transmisiones de StreamingPull siempre se cierran con un error, no es útil
examinar las métricas de finalización de la transmisión mientras se diagnostican los errores. En su lugar, concéntrate en
la métrica de respuesta de StreamingPull
subscription/streaming_pull_response_count,
agrupada por response_code o response_class.
Busca estos errores:
Los errores de condición previa con errores pueden ocurrir si hay mensajes en la lista de tareas pendientes de la suscripción que están encriptados con una clave de Cloud KMS inhabilitada. Para reanudar la extracción, restablece el acceso a la clave.
Los errores de falta de disponibilidad pueden ocurrir cuando Pub/Sub no puede procesar una solicitud. Lo más probable es que esta sea una condición transitoria y que la biblioteca cliente vuelva a intentar las solicitudes. No es necesario que realices ninguna acción si usas una biblioteca cliente.
Los errores de no encontrado pueden ocurrir cuando se borra la suscripción o si nunca existió. Este último caso ocurre si proporcionaste una ruta de suscripción no válida.