[Message Queue Server] Mejores prácticas para desbloquear la implementación del clúster RocketMQ de fallas de producción

I. Introducción

Cerca de fin de año, una falla en la memoria de la máquina física en el clúster MQ de producción mantenido por el autor hizo que el sistema operativo se reiniciara de manera anormal. En 10 minutos, muchas aplicaciones que envían clientes experimentaron tiempos de espera de envío de mensajes. El accidente se identificó como S1, el "bonificación de fin de año" del autor ...

1.1 Descripción de la avería

La arquitectura de implementación adoptada por el clúster RocketMQ es 2 maestros y 2 esclavos. La arquitectura de implementación se muestra en la siguiente figura:

Una característica muy obvia de su arquitectura de implementación es la implementación de servidores de nombres y procesos de intermediario en una máquina física.

Una de las máquinas (192.168.3.100) tuvo una falla de memoria, lo que provocó que la máquina se reiniciara. Sin embargo, debido a factores como la autoverificación necesaria para reiniciar el sistema operativo Linux, todo el proceso de reinicio duró casi 10 minutos y El tiempo de espera de envío del cliente duró 10 minutos ¡Esto es obviamente inaceptable! ! !

¿Cuál es el diseño de alta disponibilidad de RocketMQ? A continuación, presentaremos el proceso de análisis en detalle .

1.2 Análisis de fallas

Cuando supe que una falla en la máquina provocó que el tiempo de espera de envío de mensajes durara 10 minutos, mi primera reacción fue que no debería, porque el clúster de RocketMQ es una arquitectura de implementación distribuida, que naturalmente admite la detección y recuperación de fallas, y el envío de mensajes El cliente puede percibir automáticamente al corredor. El tiempo anormal nunca excederá los 10 minutos, entonces, ¿cómo sucedió la falla?

Primero, revisemos el mecanismo de descubrimiento y registro de enrutamiento de RocketMQ.

(1) Mecanismo de eliminación y registro de enrutamiento de RocketMQ

El mecanismo de registro y eliminación de enrutamiento se describe a continuación:

  • Todos los agentes del clúster envían paquetes de latidos a todos los servidores de nombres del clúster cada 30 segundos para registrar la información de enrutamiento del tema.
  • Cuando NameServer recibe un paquete de latidos del lado del Broker, primero actualiza la tabla de enrutamiento y registra la hora en que se recibe el paquete de latidos.
  • NameServer inicia una tarea programada para escanear la tabla de estado de supervivencia del corredor cada 10 segundos. Si el servidor de nombres no recibe el paquete de latido del corredor durante 120 segundos, determinará que el corredor está fuera de línea y eliminará al corredor de la tabla de enrutamiento.
  • Si se desconecta la conexión larga entre el servidor de nombres y el intermediario, el servidor de nombres puede detectar inmediatamente que el intermediario está fuera de línea y eliminar al intermediario de la tabla de enrutamiento.
  • El cliente de mensajes (remitente de mensajes, consumidor de mensajes) solo establecerá una conexión con uno de los NameServers en cualquier momento y consultará al NameServer para obtener información de enrutamiento cada 30 segundos. Si se encuentran los resultados de la consulta, la información de enrutamiento local del cliente se actualizará; si se consulta el enrutamiento Si falla, ignórelo.

A juzgar por el mecanismo de eliminación y registro de enrutamiento anterior, cuando un servidor Broker está inactivo, ¿cuánto tiempo tarda el remitente del mensaje en percibir los cambios en la información de enrutamiento?

Discuta por separado en las siguientes dos situaciones:

  • La conexión TCP entre NameServer y el servidor Broker está desconectada. En este momento, NameServer puede percibir inmediatamente el cambio de información de enrutamiento y eliminarlo de la tabla de enrutamiento, de modo que el remitente del mensaje debería poder percibir el cambio de enrutamiento en 30 segundos. El remitente lo hará. Si un mensaje no se envía, pero combinado con el mecanismo de evasión de envío, no causará fallas importantes al remitente, lo cual es aceptable.
  • Si la conexión TCP entre el servidor de nombres y el servidor del intermediario no está desconectada, pero el intermediario ya no puede proporcionar servicios (como la animación suspendida), el servidor de nombres tarda 120 segundos en detectar el tiempo de inactividad del intermediario y, en este momento, aparece el mensaje El remitente necesita hasta 150 segundos para detectar los cambios en su información de enrutamiento.

Pero la pregunta es, ¿por qué un Broker se reinicia debido a una falla de memoria y el negocio se reanuda solo después de 10 minutos, es decir, el cliente realmente siente que el Broker no funciona?

Ahora que aparece, necesitamos analizarlo y dar una solución para evitar el mismo tipo de error en el entorno de producción.

(2) Después de la resolución de problemas

Consulta el registro del cliente (/home/{user}/logs/rocketmqlogs/rocketmq_client.log), desde el cual puedes ver que la hora de enviar un mensaje desde el cliente por primera vez es 14:44. La salida del registro es como sigue:

Debido a la falla de memoria de la máquina 192.168.3.100, primero verifique los registros en otros servidores de nombres en el clúster para ver cuánto tiempo el NameServer en la máquina normal percibe la falla del broker-a. Los registros son los siguientes:

Se puede ver a partir de esto que el servidor de nombres de 192.18.3.101 básicamente detecta su tiempo de inactividad en aproximadamente 2 minutos, es decir, aunque la máquina se está reiniciando, es posible que la conexión TCP no se desconecte debido a la autocomprobación del hardware del sistema operativo y otras razones, por lo que el servidor de nombres detecta su tiempo de inactividad después de 120 segundos y elimina al corredor de la tabla de información de enrutamiento. Luego, de acuerdo con el mecanismo de eliminación de enrutamiento, el cliente debería percibir el cambio en 150 segundos, entonces, ¿por qué no lo percibió? ?

Continúe viendo la información de enrutamiento del cliente y vea el momento en el que el cliente percibe cambios en la información de enrutamiento, como se muestra en la siguiente figura:

Desde el registro del cliente, el cliente solo percibe el cambio a las 14:53:46. ¿Por qué?

Resulta que el cliente informó una excepción de tiempo de espera al actualizar la información de enrutamiento. La captura de pantalla se muestra a continuación:

Durante el período desde el fallo hasta la recuperación del fallo, el cliente ha intentado actualizar la información de enrutamiento del NameServer fallido, pero siempre ha devuelto un tiempo de espera, lo que ha provocado que el cliente no pueda obtener la información de enrutamiento más reciente, por lo que no ha podido sentir que ha caído.

Desde el punto de vista del análisis de registros, hasta ahora es relativamente claro. Todos los clientes no percibieron el cambio de su información de enrutamiento dentro de 120 s, porque el cliente ha estado tratando de actualizar la información de enrutamiento desde el servidor de nombres caído, pero porque El la solicitud no ha tenido éxito, por lo que la información de enrutamiento en caché del cliente no se ha podido actualizar, lo que provoca el fenómeno anterior

El problema está aquí. Según nuestro entendimiento de RocketMQ, el servidor de nombres está inactivo y el cliente seleccionará automáticamente el siguiente servidor de nombres de la lista de servidores de nombres. ¿Por qué el cambio de servidor de nombres no ocurre aquí , sino que espera hasta las 14:53?

A continuación, nos centraremos en el código de conmutación de NameServer, el fragmento de código se muestra en la siguiente figura:

Varios análisis clave en la figura anterior son los siguientes:

  • El requisito previo para que el cliente seleccione la conexión de la caché para enviar la solicitud RPC es que el método isActive de la conexión devuelva verdadero, es decir, que la conexión TCP subyacente esté activa.
  • Cuando el cliente inicia una solicitud RPC al servidor, si ocurre una excepción sin tiempo de espera, se ejecutará el método closeChannel. Este método cerrará la conexión y la eliminará de la tabla de caché de conexiones. Esto es muy importante, porque si hay un caché al cambiar el servidor de nombres Si la conexión está activa y la conexión está activa, el servidor de nombres no se cambiará.
  • Si el RPC de envío se agota, rocketmq decidirá si cerrar la conexión de acuerdo con el parámetro clientCloseSocketIfTimeout, pero desafortunadamente este parámetro es falso por defecto y no se proporciona ninguna entrada de modificación.

El análisis del problema aquí es muy claro.

Debido a factores como la falla de la memoria de la máquina que desencadena un reinicio y la necesidad de autocomprobación, el servidor de nombres y el intermediario ya no pueden procesar la solicitud, pero la conexión TCP subyacente no se desconecta. Vuelve después de un tiempo de espera, pero el cliente no cierre la conexión TCP con el servidor de nombres de la máquina fallida. Se activará la conmutación de NameServer. Después de que la máquina se reinicie correctamente, la conexión TCP se desconecta. Después de reiniciarse la máquina defectuosa, detectará los cambios en la información de enrutamiento y se recuperará de la falla.

Causa raíz: la animación suspendida del servidor de nombres provocó que la información de enrutamiento no se actualizara.

(3) Mejores prácticas

Después de las fallas anteriores, personalmente creo que el servidor de nombres no debe implementarse con el agente. Si el servidor de nombres y el agente no se implementan juntos, los problemas anteriores se pueden evitar de manera efectiva. La arquitectura de implementación se muestra en la siguiente figura:

Si dicha arquitectura de implementación se enfrenta al escenario anterior, es decir, animación suspendida del agente, ¿se puede evitar de manera efectiva? La respuesta es sí.

Si el intermediario de 192.168.3.100 está suspendido, los servidores de nombres de 3.110 y 3.111 pueden percibir que el intermediario-a está inactivo en 2 minutos, y el cliente puede obtener la información de enrutamiento más reciente del servidor de nombres, de modo que no seguirá funcionando. inactivo cuando se envía el mensaje El corredor continúa enviando mensajes y se restaura la falla;

Si el servidor de nombres se suspende y se produce un error de tiempo de espera, siempre que el intermediario no esté inactivo, la caché aún puede funcionar normalmente, pero si el nanmeserver y el intermediario se suspenden juntos, la arquitectura anterior aún no puede evitar los problemas anteriores .

Por lo tanto, esta vez la mejor práctica incluye principalmente las dos medidas siguientes :
1. El servidor de nombres y el intermediario deben implementarse por separado y aislarse.
2. La conexión entre el servidor de nombres y el cliente debe cerrarse después del tiempo de espera para activar la deriva del servidor de nombres, y el código fuente debe modificarse.

 

 

 

 

 

 

 

 

 

 

Supongo que te gusta

Origin blog.csdn.net/qq_41893274/article/details/112546934
Recomendado
Clasificación