Análisis del código fuente de RocketMQ: ¿cómo solucionar la pérdida de mensajes?

Por favor agregue la descripción de la imagen

¿Cómo solucionar la pérdida de mensajes?

Cuando usamos mq, a menudo nos encontramos con el problema del consumo anormal de mensajes. Hay muchas razones, como

  1. el envío del productor falló
  2. Excepción de consumo del consumidor
  3. el consumidor no recibió el mensaje en absoluto

Entonces, ¿cómo investigamos?


inserte la descripción de la imagen aquí
De hecho, con la ayuda de RocketMQ -Dashboard, puede verificar de manera eficiente, hay muchas funciones que no puede imaginar

¿Mensaje no encontrado?

Significa que el productor se envía de forma anormal o el mensaje ha caducado, porque el mensaje de Rocketmq se guarda durante 72 horas de forma predeterminada. En este momento, vaya al registro del productor para obtener más confirmación.

¡Mensaje encontrado!

Luego mire el estado de consumo del mensaje, como se muestra en la figura a continuación, el estado de consumo del mensaje es NOT_ONLINE

inserte la descripción de la imagen aquí
¿Qué significa NOT_ONLINE?

No te preocupes, analicémoslo paso a paso, veamos cuántos estados tiene TrackType.

public enum TrackType {
    
    
    CONSUMED,
    CONSUMED_BUT_FILTERED,
    PULL,
    NOT_CONSUME_YET,
    NOT_ONLINE,
    UNKNOWN
}

A continuación se explica cada tipo

Tipos de explicar
CONSUMADO el mensaje ha sido consumido
CONSUMIDO_PERO_FILTRADO El mensaje fue entregado pero filtrado
JALAR La forma de consumo de mensajes es el modo pull.
NO_CONSUMIR_AUN no consumido actualmente
FUERA DE LINEA EL CONSUMIDOR está desconectado
DESCONOCIDO error desconocido

¿Cómo determinar que el mensaje ha sido consumido?

Como mencionamos en la sección anterior, el broker utilizará un mapa para guardar el progreso de consumo de cada cola, si el desplazamiento de la cola es mayor que el desplazamiento del mensaje consultado, el mensaje será consumido, de lo contrario no será consumido (NO_CONSUME_AUN)

¿Es posible saber inmediatamente dónde está el problema?

CONSUMED_BUT_FILTERED indica que el mensaje se entregó, pero se filtró . Por ejemplo, el productor envía topicA, tagA, pero el consumidor se suscribe a topicA, tagB

En RocketMQ-Dashboard, podemos ver el desplazamiento (sitio del agente) de cada agente de cola y el desplazamiento (sitio del consumidor) del consumo de mensajes. La diferencia son los mensajes que no se consumen.
inserte la descripción de la imagen aquí
Cuando se consumen todos los mensajes, la diferencia es 0 , como se muestra en la siguiente figura

inserte la descripción de la imagen aquí
¿Cómo sucede CONSUMED_BUT_FILTERED (mensaje entregado pero filtrado)?

Esto tiene que mencionar un concepto en RocketMQ. El consumo de mensajes debe cumplir con la consistencia de la relación de suscripción, es decir, los temas y etiquetas suscritos por todos los consumidores en un grupo de consumidores deben ser consistentes, de lo contrario, los mensajes se perderán.

Como se muestra en el siguiente escenario, se envían 4 mensajes, el consumidor 1 se suscribe a topica-taga y el consumidor 2 se suscribe a topica-tab. consumidor1 consume datos en q0, consumidor2 consume datos en q1

Para el mensaje-1 y el mensaje-3 enviados a q0, solo el mensaje-1 se puede consumir normalmente, mientras que el mensaje-3 es CONSUMIDO_PERO_FILTRADO. Debido a que msg-3 se entrega a q0, pero consumidor1 no consume el mensaje de tagb, el mensaje se filtra y el mensaje se pierde

Del mismo modo msg-2 este mensaje también se perderá
inserte la descripción de la imagen aquí

Tenga en cuenta que hay otro punto muy importante

Aunque el consumo del mensaje falla, el desplazamiento del mensaje se enviará normalmente, es decir, el consumo del mensaje falla, pero el estado también será CONSUMIDO

Entonces, ¿adónde fue la noticia del fracaso del consumo?

Cuando el consumo de mensajes falla, se colocará en la cola de reintentos y el nombre del tema es %RETRY% + ConsumerGroup

El consumidor no se suscribe a este tema, ¿cómo puede consumir mensajes de reintento?
inserte la descripción de la imagen aquí
De hecho, cuando se inicia el Consumidor, el marco se suscribe a este tema por usted, por lo que el mensaje de reintento se puede consumir para

Además, el mensaje no se vuelve a intentar todo el tiempo, sino cada 1 período de tiempo.

número de veces para reintentar intervalo de tiempo desde el último reintento número de veces para reintentar intervalo de tiempo desde el último reintento
1 10 segundos 9 7 minutos
2 30 segundos 10 8 minutos
3 1 minuto 11 9 minutos
4 2 minutos 12 10 minutos
5 3 minutos 13 20 minutos
6 4 minutos 14 30 minutos
7 5 minutos 15 1 hora
8 6 minutos dieciséis 2 horas

Cuando el mensaje supera los tiempos máximos de consumo de 16 veces, el mensaje se enviará a la cola de mensajes fallidos. El nombre del tema de la cola de mensajes fallidos es %DLQ% + ConsumerGroup.

Por lo tanto, cuando encuentre que el estado del mensaje es CONSUMIDO, pero el consumo falla, simplemente vaya a la cola de reintentos y a la cola de mensajes fallidos para encontrarlo.

Solución de problemas de excepción de consumo de mensajes

El trasfondo de este problema es este, es decir, tenemos dos sistemas, y la consistencia de los datos está asegurada por mq en el medio, como resultado, un día los datos son inconsistentes, debe ser un problema con el consumidor que consume mensajes, o el productor enviando mensajes.

Primero busque el mensaje según el período de tiempo para asegurarse de que no haya ningún problema en el envío, y luego vea que el estado del mensaje es NOT_CONSUME_YET, lo que indica que el consumidor está en línea pero no hay ningún mensaje.

Por favor agregue la descripción de la imagen
NOT_CONSUME_YET indica que el mensaje no se ha consumido , pero ha pasado mucho tiempo desde que se envió el mensaje. El consumidor no debería haberlo consumido. Verifique en el registro que el consumidor no lo consumió.

Use RocketMQ-Dashboard para verificar el sitio del agente y el sitio del consumidor. La cola 0 consume normalmente y otras colas no se consumen
inserte la descripción de la imagen aquí
. Siento que esta estrategia de equilibrio de carga es un poco problemática, por qué hay tantos mensajes en la cola 0 y por qué no hay mensajes en otras colas. Pregunte a una ola de estudiantes de middleware, ¿han vuelto a cambiar la estrategia de equilibrio de carga?

¡Ciertamente ha cambiado! En el entorno de prueba, la latitud de la cola se utiliza para distinguir varios entornos. 0 es el entorno de referencia. Nuestro equipo aún no ha utilizado varios entornos, por lo que los mensajes enviados y recibidos estarán en la cola 0 y no se utilizarán otras colas ( simplemente puede pensar que el entorno de prueba envía y consume El mensaje solo usará la cola 0 )

¡Entonces aquí viene el problema!

En primer lugar, el estado del mensaje es NOT_CONSUME_YET, lo que significa que el mensaje debe haberse entregado a la cola 0, pero el socio de middleware dijo que el mensaje no se entregará a la cola 0.

Para verificar mi idea, primero debemos demostrar que los mensajes que no se han consumido se envían a colas distintas de la cola 0.

No hablaré sobre los desvíos en el medio, hasta que miré el código fuente de RocketMQ-Dashboard y descubrí que Dashboard en realidad devolvía mucha información del mensaje, pero no se mostraba en la página. la interfaz y volví a
inserte la descripción de la imagen aquí
darling, y encontré un nuevo mundo, noticias Todas las propiedades de . están aquí, y viendo que el queueId es 14, realmente verificó mi idea.

Veamos que bornHost es en realidad el segmento de red de nuestra oficina

¿La estrategia de equilibrio de carga se inicia localmente y la estrategia de equilibrio de carga del entorno de prueba es diferente?

Una ola de código de depuración local, resulta que el productor local enviará mensajes a todas las colas y el consumidor también consumirá mensajes de todas las colas.

¡Hasta ahora se ha encontrado el problema!

El productor inicia un servicio localmente, se registra con el zk del entorno de prueba, algunas solicitudes del entorno de prueba se envían al local y los mensajes se envían a las colas que no sean la cola 0, pero el consumidor del entorno de prueba solo consume los mensajes en la cola 0, lo que da como resultado que el mensaje no se haya consumido durante mucho tiempo

parámetro

[1]http://www.broadview.com.cn/article/419768
[2]https://mp.weixin.qq.com/s/wWgAbFLuesdb3BhY3GjxPg

Supongo que te gusta

Origin blog.csdn.net/zzti_erlie/article/details/123558837
Recomendado
Clasificación