Cómo solucionar problemas relacionados con una suscripción de extracción

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 del suscriptor de extracción.

Para supervisar de manera eficaz tu suscripción de Pub/Sub, te recomendamos que primero observes 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 aumentada.

La antigüedad del mensaje sin confirmación más antiguo sigue aumentando

The oldest_unacked_message_age es una métrica fundamental para supervisar el estado de las suscripciones de Pub/Sub. Mide la antigüedad, en segundos, del mensaje más antiguo en el trabajo acumulado de una suscripción que aún no confirmó un suscriptor. Esta métrica ofrece información valiosa sobre posibles retrasos o cuellos de botella en el procesamiento.

Supervisar el trabajo acumulado de mensajes garantiza un procesamiento oportuno y eficiente de los mensajes. Si realizas un seguimiento de la antigüedad del mensaje sin confirmación más antiguo, puedes identificar de forma proactiva 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 el rendimiento degradado.

Estos son algunos de los problemas comunes de trabajos acumulados 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 CPU, memoria y ancho de banda de la red. Busca puntos de presión que puedan impedir la eficiencia del procesamiento.

  • Código del cliente: Revisa los cambios de código recientes y examina los registros de errores. Los errores o las ineficiencias en el código del suscriptor pueden afectar de manera significativa 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 en una base de datos de forma simultánea. Este comportamiento puede generar contención y latencia alta.

  • Limitaciones de cuota: Verifica que no hayas superado ninguna cuota o limitación de Pub/Sub impuesta por tu servicio de hosting. Si los suscriptores están alojados en Google Cloud, revisa las cuotas de recursos de Compute Engine o GKE para evitar posibles cuellos de botella.

El suscriptor confirmó los mensajes de forma negativa

Cuando un suscriptor confirma un mensaje de forma negativa (nack), le indica a Pub/Sub que el mensaje no se pudo procesar correctamente. Luego, Pub/Sub intenta volver a entregar el mismo mensaje. Los nacks repetidos para un mensaje generan duplicados y, posiblemente, un retraso alto en la entrega de mensajes.

Ten en cuenta que el nack de un mensaje no garantiza que la próxima extracción recupere un mensaje diferente. Es posible que la política de reenvío de Pub/Sub continúe reenviando mensajes nacked 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, preferentemente una retirada exponencial, como una forma de retirarse de los mensajes individuales que probablemente se puedan procesar 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 procesas. Esto los quita de la suscripción, evita reenvíos innecesarios y reduce el consumo de recursos. Dejar mensajes sin confirmar, ya sea de forma intencional o no, crea problemas de trabajos acumulados 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 posibles causas de una latencia de entrega alta.

No hay suficientes suscriptores

Para los clientes que usan StreamingPull, para lograr una latencia baja de manera constante, mantén varias conexiones de StreamingPull abiertas a tu suscripción. Sin conexiones de suscriptores activas, Pub/Sub no puede entregar mensajes de inmediato. Una sola transmisión podría ser un punto único de falla, 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. Úsala para asegurarte de tener suficientes transmisiones de manera constante para controlar los mensajes entrantes.

Para los clientes que usan la extracción unaria, para lograr una latencia baja de manera constante, mantén varias solicitudes de extracción pendientes en tu suscripción. Las solicitudes poco frecuentes podrían acumular mensajes en el trabajo acumulado y aumentar la latencia. Este enfoque ayuda a minimizar las brechas en la conectividad y a mejorar la latencia de entrega.

Se recomienda la biblioteca cliente de alto nivel para los casos en los que necesitas una alta capacidad de procesamiento y una latencia baja 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 integradas previamente 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 mensajes y otras funciones.

Problemas de configuración del cliente

Consulta Problemas de configuración del cliente.

Tareas pendientes

Ten en cuenta que un trabajo acumulado de mensajes sin confirmación en una suscripción de Pub/Sub aumenta de forma inherente la latencia de extremo a extremo porque los suscriptores no procesan los mensajes de inmediato.

Claves de ordenamiento y entrega “exactamente una vez”

Las claves de ordenamiento y la entrega “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 tasa de error aumentada. 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 ordenamiento de mensajes o la entrega “exactamente una vez” son absolutamente esenciales para tu aplicación. Si la latencia baja es tu prioridad principal, minimizar el uso de estas funciones podría ayudar a reducir los retrasos en el procesamiento de mensajes.

Aumento en el tamaño del mensaje

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 topic/message_sizes métrica, agrupando por topic_id. Correlaciona cualquier aumento repentino en el tamaño del mensaje 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 que contribuye.

Distribución de mensajes en suscripciones de Pub/Sub con varios consumidores

En Pub/Sub, los mensajes pueden distribuirse de manera desigual entre los consumidores de la misma suscripción. Pub/Sub balancea la carga de mensajes en todos los clientes activos, pero el objetivo principal es maximizar la capacidad de procesamiento general de mensajes y minimizar el trabajo acumulado, 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 los mensajes con rapidez y no están restringidos por su configuración de control de flujo. Es probable que los consumidores que procesan mensajes a diferentes velocidades o que operan en diferentes condiciones (p.ej., disponibilidad de recursos, latencia de red) controlen 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 en varios consumidores significa que el orden en el 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 los mensajes ya podrían estar pendientes para los clientes, y un trabajo acumulado 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 usa la extracción en la Google Cloud consola o Google Cloud CLI, o que ejecuta un suscriptor personalizado de forma local para verificar los mensajes.

Para los clientes de extracción unaria, es posible que observes que algunas solicitudes de extracción muestran cero mensajes. Como se explicó en la sección No hay suficientes suscriptores, se recomienda mantener varias solicitudes de extracción pendientes, ya que algunas solicitudes podrían mostrar menos que la cantidad máxima de mensajes configurados, o incluso cero mensajes, incluso si existe un trabajo acumulado. Esto se debe a que otros consumidores podrían tener arrendamientos sobre los mensajes disponibles.

Si un consumidor no confirma un mensaje dentro del plazo de confirmación o si lo confirma de forma negativa (NACK), Pub/Sub intentará volver a entregarlo. Este intento de reenvío se puede realizar a cualquier consumidor activo en la suscripción, no necesariamente al que lo recibió inicialmente. Por lo tanto, se puede entregar un ID de mensaje en particular 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 de forma simultánea a la suscripción y revisa sus métricas y configuraciones de rendimiento individuales.

Filtro 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 trabajos acumulados.

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 no muestra mensajes. Esto puede hacer que las solicitudes de extracción muestren 0 mensajes, incluso cuando hay un trabajo acumulado.

Problemas de configuración del cliente

Si usas la biblioteca cliente de Java y estás inicializando tu suscriptor con un canal gRPC personalizado mediante el setChannelProvider() método, debes asegurarte de que el maxInboundMessageSize parámetro de configuración 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 sean más grandes que maxInboundMessageSize no se recibirán correctamente. Algunos métodos comunes para configurar este parámetro son InstantiatingGrpcChannelProvider.Builder.setMaxInboundMessageSize() y ManagedChannelBuilder.maxInboundMessageSize().

Cómo abordar los duplicados

La duplicación de mensajes en Pub/Sub suele ocurrir cuando los suscriptores no pueden confirmar los mensajes dentro del plazo de confirmación. Esto hace que los mensajes se vuelvan a entregar, lo que crea la impresión de duplicados. Puedes medir la frecuencia con la que los suscriptores no cumplen el plazo 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 manejan la extensión de plazos de forma automática, pero existen límites máximos predeterminados para la extensión que puedes configurar.
  • Si creas tu propia biblioteca cliente, usa el modifyAckDeadline método para extender el plazo 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. En el peor de los casos, esto puede hacer que un suscriptor se desborde con duplicados, lo que exacerba el trabajo acumulado. Los duplicados vencidos generan duplicados nuevos.

Para evitar sobrecargar al suscriptor, reduce la cantidad de mensajes que extrae el suscriptor a la vez. De esta manera, el suscriptor tiene menos mensajes para procesar dentro del plazo. Vencen menos mensajes y se vuelven a entregar menos mensajes.

Para reducir la cantidad de mensajes que extrae el suscriptor a la vez, debes reducir la configuración de la cantidad máxima de mensajes pendientes en la configuración de control de flujo de tu suscriptor. No hay 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 del suscriptor. Ten en cuenta que cada aplicación procesa los mensajes de manera diferente y tarda una cantidad de tiempo diferente en confirmar un mensaje.

Fuerza reintentos

Para forzar a Pub/Sub a volver a 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 confirmaron anteriormente. 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 la confirmación correcta de los mensajes anteriores en la secuencia.

El suscriptor está nacking los mensajes

Consulta el suscriptor está nacking los mensajes.

Soluciona problemas relacionados con una suscripción de StreamingPull

Relación entre la métrica de latencia de solicitud y la latencia de entrega de extremo a extremo

Para 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 solicitud, usa la puntuación de estado de la latencia de entrega para verificar qué factores contribuyen a una mayor latencia de entrega de extremo a extremo.

Las conexiones de StreamingPull se cierran con un estado que no es correcto

Las transmisiones de StreamingPull siempre se cierran con un estado que no es correcto. A diferencia de un estado de error para los RPC unarios, este estado para StreamingPull es solo un indicador de que la transmisión está desconectada. Las solicitudes no fallan. Por lo tanto, aunque la API de StreamingPull puede tener una tasa de error del 100% sorprendente, este comportamiento es por diseño.

Debido a que las transmisiones de StreamingPull siempre finalizan con un error, no es útil examinar las métricas de finalización de la transmisión cuando diagnosticas errores. Más bien, 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:

  • Pueden producirse errores de condición previa fallida si hay mensajes en el trabajo acumulado de suscripciones que están encriptadas por una clave de Cloud KMS inhabilitada. Para reanudar la extracción, restablece el acceso a la clave.

  • Pueden producirse errores no disponibles cuando Pub/Sub no puede procesar una solicitud. Lo más probable es que se trate de una condición transitoria y que la biblioteca cliente vuelva a intentar las solicitudes. No es necesaria ninguna acción de tu parte si usas una biblioteca cliente.

  • Pueden producirse errores no encontrados cuando se borra la suscripción o si nunca existió. El último caso ocurre si proporcionaste una ruta de acceso de suscripción no válida.

Referencias adicionales: