Solución de problemas del procesador de eventos de Azure Event Hubs
En este artículo se proporcionan soluciones a problemas comunes que pueden surgir al usar el EventProcessorClient
tipo . Si busca soluciones a otros problemas comunes que podrían surgir al usar Azure Event Hubs, consulte Solución de problemas de Azure Event Hubs.
412 errores de condición previa cuando se usa un procesador de eventos
412 errores de condición previa se producen cuando el cliente intenta tomar o renovar la propiedad de una partición, pero la versión local del registro de propiedad está obsoleta. Este problema se produce cuando otra instancia del procesador roba la propiedad de la partición. Para obtener más información, vea la siguiente sección.
Cambios de propiedad de partición con frecuencia
Cuando cambia el número de EventProcessorClient
instancias (es decir, se agregan o quitan), las instancias en ejecución intentan equilibrar la carga de particiones entre sí mismas. Durante unos minutos después del número de cambios de procesadores, se espera que las particiones cambien los propietarios. Una vez equilibrada, la propiedad de la partición debe ser estable y cambiar con poca frecuencia. Si la propiedad de la partición cambia con frecuencia cuando el número de procesadores es constante, es probable que indique un problema. Se recomienda que registre un problema de GitHub con registros y una reproducción.
La propiedad de la partición se determina a través de los registros de propiedad de CheckpointStore
. En cada intervalo de equilibrio de carga, EventProcessorClient
realizará las siguientes tareas:
- Capture los registros de propiedad más recientes.
- Compruebe los registros para ver qué registros no han actualizado su marca de tiempo dentro del intervalo de expiración de la propiedad de la partición. Solo se tienen en cuenta los registros que coinciden con estos criterios.
- Si hay particiones noowned y la carga no está equilibrada entre instancias de
EventProcessorClient
, el cliente del procesador de eventos intentará reclamar una partición. - Actualice el registro de propiedad de las particiones que posee y que tenga un vínculo activo a esa partición.
Puede configurar los intervalos de expiración de propiedad y equilibrio de carga al crear mediante EventProcessorClient
, EventProcessorClientBuilder
como se describe en la lista siguiente:
- El método loadBalancingUpdateInterval(Duration) indica con qué frecuencia se ejecuta el ciclo de equilibrio de carga.
- El método partitionOwnershipExpirationInterval(Duration) indica la cantidad mínima de tiempo desde que se ha actualizado el registro de propiedad, antes de que el procesador considere una partición sin propietario.
Por ejemplo, si un registro de propiedad se actualizó a las 9:30 a.m. y partitionOwnershipExpirationInterval
es de 2 minutos. Cuando se produce un ciclo de equilibrio de carga y observa que el registro de propiedad no se ha actualizado en los últimos 2 minutos o a las 9:32 a. m., tendrá en cuenta la partición sin propietario.
Si se produce un error en uno de los consumidores de particiones, cerrará el consumidor correspondiente, pero no intentará reclamarlo hasta el siguiente ciclo de equilibrio de carga.
"... el receptor actual "<RECEIVER_NAME>" con la época "0" se está desconectando"
El mensaje de error completo es similar al siguiente resultado:
New receiver 'nil' with higher epoch of '0' is created hence current receiver 'nil' with epoch '0'
is getting disconnected. If you are recreating the receiver, make sure a higher epoch is used.
TrackingId:<GUID>, SystemTracker:<NAMESPACE>:eventhub:<EVENT_HUB_NAME>|<CONSUMER_GROUP>,
Timestamp:2022-01-01T12:00:00}"}
Este error se espera cuando se produce el equilibrio de carga después EventProcessorClient
de agregar o quitar instancias. El equilibrio de carga es un proceso en curso. Cuando se usa BlobCheckpointStore
con el consumidor, cada 30 segundos (de forma predeterminada), el consumidor comprueba qué consumidores tienen una notificación para cada partición y, a continuación, ejecuta alguna lógica para determinar si necesita "robar" una partición de otro consumidor. El mecanismo de servicio que se usa para afirmar la propiedad exclusiva sobre una partición se conoce como La época.
Sin embargo, si no se agregan o quitan instancias, hay un problema subyacente que se debe solucionar. Para obtener más información, consulte la sección Cambios de propiedad de particiones con frecuencia y Presentación de problemas de GitHub.
Uso elevado de CPU
El uso elevado de la CPU suele deberse a que una instancia posee demasiadas particiones. Se recomienda no más de tres particiones para cada núcleo de CPU. Es mejor empezar con 1,5 particiones para cada núcleo de CPU y, a continuación, probar aumentando el número de particiones propiedad.
Memoria insuficiente y elección del tamaño del montón
El problema de memoria insuficiente (OOM) puede ocurrir si el montón máximo actual de la JVM no es suficiente para ejecutar la aplicación. Es posible que quiera medir el requisito del montón de la aplicación. A continuación, en función del resultado, ajuste el tamaño del montón estableciendo la memoria máxima del montón adecuada mediante la -Xmx
opción JVM.
No debe especificar -Xmx
como un valor mayor que la memoria disponible o el límite establecido para el host (la máquina virtual o el contenedor), por ejemplo, la memoria solicitada en la configuración del contenedor. Debe asignar suficiente memoria para que el host admita el montón de Java.
En los pasos siguientes se describe una manera típica de medir el valor del montón máximo de Java:
Ejecute la aplicación en un entorno cercano a producción, donde la aplicación envía, recibe y procesa eventos bajo la carga máxima esperada en producción.
Espere a que la aplicación alcance un estado estable. En esta fase, la aplicación y JVM habrían cargado todos los objetos de dominio, tipos de clase, instancias estáticas, grupos de objetos (TCP, grupos de conexiones de base de datos), etc.
En el estado estable, verá el patrón estable con forma de sawtooth para la colección del montón, como se muestra en la captura de pantalla siguiente:
Una vez que la aplicación alcanza el estado estable, fuerza una recolección completa de elementos no utilizados (GC) mediante herramientas como JConsole. Observe la memoria ocupada después de la gc completa. Desea ajustar el tamaño del montón de modo que solo el 30 % esté ocupado después del GC completo. Puede usar este valor para establecer el tamaño máximo del montón (mediante
-Xmx
).
Si está en el contenedor, cambie el tamaño del contenedor para que tenga aproximadamente 1 GB de memoria para la instancia de JVM que no sea del montón.
El cliente del procesador deja de recibir
El cliente del procesador a menudo se ejecuta continuamente en una aplicación host durante días al final. A veces, observa que EventProcessorClient
no está procesando una o varias particiones. Normalmente, no hay suficiente información para determinar por qué se produjo la excepción. La EventProcessorClient
detención es el síntoma de una causa subyacente (es decir, la condición de carrera) que se produjo al intentar recuperarse de un error transitorio. Para obtener la información que necesitamos, consulte Presentación de problemas de GitHub.
EventData duplicado recibido cuando se reinicia el procesador
El EventProcessorClient
servicio y Event Hubs garantizan una entrega al menos una vez . Puede agregar metadatos para distinguir eventos duplicados. Para más información, consulte ¿Azure Event Hubs garantiza una entrega al menos una vez? en Stack Overflow. Si necesita la entrega solo una vez , debe tener en cuenta Service Bus, que espera una confirmación del cliente. Para obtener una comparación de los servicios de mensajería, consulte Elección entre los servicios de mensajería de Azure.
Migración de la biblioteca cliente heredada a la nueva
La guía de migración incluye pasos para migrar desde el cliente heredado y migrar puntos de control heredados.
Pasos siguientes
Si la guía de solución de problemas de este artículo no ayuda a resolver problemas al usar las bibliotecas cliente de Azure SDK para Java, se recomienda presentar un problema en el repositorio de GitHub del SDK de Azure para Java.