[Arquitectura del sistema] Hable sobre la arquitectura y los principios del middleware de mensajería de código abierto

Hablando de middleware de mensajes, los zapatos para niños en Internet deben ser inconscientemente de alta concurrencia, se viene a la mente la programación de io de alto rendimiento, etc., pero para las aplicaciones, puede ser más que un simple rendimiento, especialmente para las transacciones. Para plataformas comerciales que se ocupan de las finanzas.

Ok, déjame presentarte en la plataforma de operaciones financieras, ¿qué escenarios requieren que usemos middleware de mensajes? ¿Por qué usarlo? ¿Cómo diseñar una nube privada de middleware para que el desarrollo sea más agradable? (En vista de las diferentes habilidades lingüísticas de los diferentes estudiantes, aquí está solo el contenido de los principios y mecanismos de diseño. Este artículo involucrará productos populares de código abierto en el mercado, como activemq, rabbitmq, kafka, metaq, etc.)

El papel del middleware de mensajes es utilizarlo como portador para la simultaneidad asíncrona. No solo eso, todavía necesita garantizar muchas capacidades en la arquitectura, alta disponibilidad, alta concurrencia, escalabilidad, confiabilidad, integridad, orden de garantía, etc. Estos ya han causado dolores de cabeza a varios diseñadores; también hay algunos requisitos anormales, como consumo lento, no repetibilidad, etc. El costo del diseño es bastante alto, así que no creas ciegamente en los expertos en código abierto. Para muchos mecanismos, casi Debe reconstruirse; no es tan sencillo crear una nube privada universal y fácil de usar que se adapte a todas las empresas.

Si un sistema de pago tiene que procesar miles de millones de pedidos comerciales todos los días, entonces la capacidad de procesamiento del middleware de mensajes debe alcanzar al menos casi 10 mil millones, porque muchos sistemas dependen de las capacidades de agrupación en clúster del middleware y deben garantizar que no haya errores, por lo tanto, dejemos Analicemos cómo lo hace el middleware desde algunos aspectos de la arquitectura.

Alta disponibilidad

La alta disponibilidad es un tema eterno. Esta también es una medida de si es confiable en el mundo financiero. Debe saber que los arquitectos de la industria financiera encontrarán formas de evitar la pérdida de datos, incluso una parte de los datos, pero de hecho, esta cosa En teoría, depende del carácter. . . Esto no es tonto.

Por ejemplo, en la arquitectura de datos de Internet, al menos tres copias de un dato se denominan garantías altas, pero de hecho, el centro de datos belga de Google se perdió permanentemente después de que cayera un rayo en 8.13, 0.000001% del centro de datos, menos de 0.05 % De los discos no se pudieron reparar. Lo que quiero decir aquí es que el momento y el lugar correctos son muy importantes. No hay nada imposible en condiciones extremas. Debe haber vulnerabilidades de arquitectura. Echemos un vistazo a la práctica general de alta disponibilidad de mq: la
siguiente imagen es activemq HA Programa:
[Arquitectura del sistema] Hable sobre la arquitectura y los principios del middleware de mensajería de código abierto

La alta disponibilidad de Activemq se gestiona mediante conmutación por error maestro / esclavo, donde la conmutación maestro-esclavo se puede cambiar de muchas maneras:
1: un bloqueo compartido se realiza a través de un nfs u otro dispositivo de disco compartido, y el maestro está marcado por la propiedad del bloqueo de archivo compartido Cuando m cuelga, el esclavo correspondiente ocupará el shared_lock y se convertirá en maestro

2: La administración de clústeres a través de zookeeper es más común. La
siguiente figura no se presenta aquí . El esquema HA de metaq es
[Arquitectura del sistema] Hable sobre la arquitectura y los principios del middleware de mensajería de código abierto
como se muestra en la figura anterior. Es exactamente el mismo, y también es el nodo maestro-esclavo de la administración de intermediarios a través de zk.

Por supuesto, este es solo uno de los mecanismos de conmutación por error, que solo puede garantizar que el mensaje se transferirá al esclavo cuando el broker se cuelgue, pero no puede garantizar la pérdida del mensaje en el proceso intermedio.

Cuando el mensaje fluye a través del intermediario, es probable que sea causado por tiempo de inactividad u otras fallas de hardware, lo que puede causar la pérdida del mensaje. En este momento, se requiere un medio de almacenamiento relevante para garantizar el mensaje.

Luego, tomamos como referencia el mecanismo de almacenamiento de Kafka. Debemos saber que la dependencia del middleware de mensajes en el almacenamiento no solo requiere una velocidad rápida, sino que también requiere requisitos de E / S de muy bajo costo. Kafka ha diseñado un conjunto de mecanismos de almacenamiento para cumplir con los requisitos anteriores, que es simple aquí. introducir.

En primer lugar, el tema en Kafka se divide en varias particiones bajo implementación distribuida. La partición es equivalente a una carga de mensajes y luego se enrutan por varias máquinas. Por ejemplo: un tema, debit_account_msg se dividirá en debit_account_msg_0, debit_account_msg_1 , debit_account_msg_2. . . Esperando N particiones, cada partición generará un directorio localmente como / debit_account_msg / topic

El archivo en el interior se dividirá en muchos segmentos, cada segmento definirá un tamaño, como 500mb un segmento, un archivo se divide en dos partes: índice y registro
00000000000000000.index
00000000000000000.log
00000000000065535.index
00000000000065535.log
donde el número representa el valor de msgId El punto de partida del índice, la estructura de datos correspondiente es la siguiente:
[Arquitectura del sistema] Hable sobre la arquitectura y los principios del middleware de mensajería de código abierto
1,0 representa el mensaje con msgId siendo 1, y 0 representa el desplazamiento en este archivo. Después de leer este archivo, busque el archivo de registro de segmento correspondiente y léalo. Información de msg correspondiente, la información correspondiente es un cuerpo de mensaje de formato fijo:
[Arquitectura del sistema] Hable sobre la arquitectura y los principios del middleware de mensajería de código abierto
Obviamente, la simple aplicación de este mecanismo definitivamente no es suficiente para cumplir con un alto IO concurrente. Primero, busque el archivo de segmento binario, luego encuentre los datos correspondientes a través de offset, luego lea msgsize, y luego Leer el cuerpo del periódico requiere al menos 4 discos io veces, lo cual es caro, pero la lectura secuencial se usa al tirar, lo que básicamente tiene poco efecto.

Además de la consulta mencionada anteriormente. De hecho, antes de escribir en el disco, todas las lecturas y escrituras se realizan en el caché de página en el sistema operativo, y luego el disco duro se vacía (estrategia LRU) periódicamente a través de subprocesos asincrónicos, pero de hecho, este riesgo es muy grande, porque una vez que el sistema operativo deja de funcionar, causará Pérdida de datos, especialmente en el caso de consumo lento y mucha acumulación de datos, pero el hermano metaq de Kafka ha realizado muchas transformaciones en esta área, y el mecanismo de replicación (utilizado por Ali) se lleva a cabo en estos archivos de partición, por lo que en este nivel No importa cómo caiga el rayo, las posibilidades de perder mensajes serán menores.Por supuesto, no descarta lo que sucede cuando se desenterra el cable óptico en la sala de acogida.

Habiendo dicho tanto, parece perfecto y hermoso, pero de hecho los costos de operación y mantenimiento parecen ser enormes. Debido a que todos estos son archivos, una vez que ocurre un problema, es bastante problemático tratarlo manualmente, y está en una sola máquina, lo que requiere costos de operación y mantenimiento relativamente grandes para realizar algunas especificaciones de operación y mantenimiento e instalaciones de llamadas a API.

Por lo tanto, en esta área, podemos almacenar datos en algunos nosql, como mongoDB. Por supuesto, mysql también es posible, pero las capacidades de io y nosqldb no están al mismo nivel a menos que tengamos un sólido mecanismo de procesamiento de transacciones. Li es bastante estricto con este requisito. Por ejemplo, metaq se usa detrás de Alipay, porque el middleware anterior tbnotify será muy pasivo en el caso de un consumo lento, y metaq tendrá una gran ventaja en esta área, por favor, escuche la descomposición más tarde.

Alta concurrencia

Al principio, la mayoría de los ingenieros usaban mq para resolver los problemas de rendimiento y asincronización. De hecho, para el mismo punto, una programación io no consume tanto recursos. Veamos algunos de los valores altos en mq. Simultaneidad, primero introduzca los antecedentes de varios middlewares conocidos:

Activemq era una solución especializada a nivel empresarial en ese momento. Cumplía con la especificación jms in jee. De hecho, el rendimiento aún era bueno, pero era un conejo sosteniendo una sandía cuando se introdujo en Internet.

Rabbitmq está escrito en lenguaje erlang, cumple con las especificaciones del protocolo AMQP y tiene una naturaleza multiplataforma. El modo de transferencia debe ser más rico y distribuido

Rocketmq (la última versión de metaq3.0 ahora, kafka también es el predecesor de metaq, originalmente el sistema de mensajes de registro de código abierto de linkedIn), metaq básicamente escribe los principios y mecanismos de kafka en java. Después de muchas modificaciones, admite transacciones. La velocidad de desarrollo es muy rápida y hay muy buenas comunidades en Ali y China para hacer este mantenimiento.

Comparación de rendimiento, aquí hay algunos datos de Internet, solo como referencia:
[Arquitectura del sistema] Hable sobre la arquitectura y los principios del middleware de mensajería de código abierto

Para ser honesto, en términos de estos niveles de datos, la diferencia no es demasiado escandalosa, pero podemos analizar algunos puntos en común, ¿dónde están estas principales diferencias de rendimiento?
Rocketmq es el sucesor de metaq. A excepción de algunas mejoras en las nuevas funciones y mecanismos, los principios de rendimiento son similares. A continuación, se muestran algunos aspectos destacados de estos de alto rendimiento:

  • El consumo de rocketmq utiliza principalmente el mecanismo de extracción. Por lo tanto, para el corredor, muchas funciones de consumo no necesitan implementarse en el corredor. Solo necesita extraer los datos relevantes a través del consumidor. Y como activemq y rabbitmq, todos toman los más antiguos. La forma de permitir que el corredor envíe el mensaje, por supuesto, algunos de los métodos de entrega estándar de jms o amqp

  • El almacenamiento de archivos se almacena secuencialmente, por lo que cuando extrae mensajes, solo necesita llamar a los datos del segmento, y el consumidor consume información en la mayor medida cuando realiza el consumo, es poco probable que genere un retraso y puede configurar io Los algoritmos de programación, como el modo noop, pueden mejorar el rendimiento de algunas lecturas secuenciales.

  • Use pagecache para golpear los datos en el caché del sistema operativo para alcanzar un consumo caliente

  • IO de disco por lotes y IO de red de Metaq, intente hacer que los datos se ejecuten en un io, los mensajes son todos lotes, de modo que la programación de io no necesite consumir demasiados recursos

  • Transmisión NIO, como se muestra en la figura siguiente, esta es una arquitectura del metaq original. Inicialmente, metaq usó algunos marcos NIO de alto rendimiento integrados con gecko y notificar-remoting dentro de Taobao para distribuir mensajes
    [Arquitectura del sistema] Hable sobre la arquitectura y los principios del middleware de mensajería de código abierto
  • Lo liviano de la cola de consumo, debemos saber que nuestra capacidad de mensaje se obtiene a través de la cola

Mire la siguiente figura:
[Arquitectura del sistema] Hable sobre la arquitectura y los principios del middleware de mensajería de código abierto
Metaq agrega una cola lógica a la cola física para consumo. Los datos del disco correspondientes a la cola se serializan. La adición de la cola no agrega la carga del disco iowait. La escritura puede ser secuencial, pero al leer Todavía es necesario usar lectura aleatoria, primera cola lógica, luego leer el disco, por lo que el caché de página es muy importante, intente aumentar la memoria, esta asignación se utilizará por completo.

De hecho, lograr lo anterior básicamente puede asegurar que nuestro desempeño esté en un nivel relativamente alto; pero a veces el desempeño no es lo más importante, lo más importante es hacer el mejor equilibrio con otras características arquitectónicas, después de todo, existen Deben satisfacerse otros mecanismos. Porque básicamente los tres problemas más difíciles de la industria: alta concurrencia, alta disponibilidad y consistencia entran en conflicto entre sí.

Escalable

Esta es una pregunta pasada de moda. Para sistemas generales o middleware, se puede extender mejor, pero en el área del middleware de mensajes, siempre ha sido un problema.

Permítanme hablar sobre las limitaciones de la expansión de activemq, porque la expansión de activemq requiere naturaleza empresarial. Como broker, primero debe conocer el origen y el destino, pero si estos mensajes son de transmisión distribuida, se volverá complicado. Echemos un vistazo a activemq. Cómo jugar con la carga.
[Arquitectura del sistema] Hable sobre la arquitectura y los principios del middleware de mensajería de código abierto
Suponemos que el productor envía mensajes del tema A. Si todos los consumidores están conectados a cada corredor en circunstancias normales, ¿qué está de moda? Si hay un mensaje del productor en el corredor, se puede transferir al correspondiente Sobre el consumidor.
Pero si no hay un mensaje correspondiente conectado a él en broker2, ¿qué debemos hacer en este caso? Dado que hay muchos nodos en el sistema de aplicación (productor) y el sistema dependiente (consumidor) del mismo tema, ¿cómo expandir la capacidad? Activemq puede hacer la parte normal en la figura anterior, pero es bastante problemático cambiar la configuración correspondiente de productor, corredor y consumidor.
Por supuesto, activemq también puede realizar búsquedas dinámicas a través de multidifusión (algunas personas también mencionaron el uso de lvs o f5 para la carga, pero existen grandes problemas para los consumidores y esta configuración de carga no tiene un efecto sustancial en la distribución de temas) Sin embargo, seguirá existiendo el problema que mencioné. Si el tema es demasiado extenso, cada broker debe conectarse con todos los productores o consumidores, de lo contrario aparecerá la situación que dije. La expansión de Activemq es bastante problemática.

Hablemos de cómo lo hace metaq. Mira la imagen.
[Arquitectura del sistema] Hable sobre la arquitectura y los principios del middleware de mensajería de código abierto
Metaq usa temas como particiones. En este nivel, solo necesitamos configurar el número de particiones de tema, de modo que solo haya una partición. El concepto de "negocio" se utiliza como una regla de enrutamiento; por lo general, se configuran varios temas en una máquina de agente, y cada tema generalmente tiene una sola partición en una máquina. Si la máquina no es suficiente, también puede admitir varias particiones. En términos generales, Puede personalizar la partición tomando el módulo de la identificación comercial, simplemente obteniendo los parámetros de la zona de envío.
[Arquitectura del sistema] Hable sobre la arquitectura y los principios del middleware de mensajería de código abierto
Los consumidores de metaq también usan el método de carga grupal (este grupo generalmente se configura de acuerdo con las capacidades de la partición) para extraer mensajes de la partición. Si hay muchos consumidores, no necesitan participar en el consumo. Este es generalmente el caso en línea, porque después de todo, el servidor de aplicaciones es mucho más grande que el servidor de mensajes.
[Arquitectura del sistema] Hable sobre la arquitectura y los principios del middleware de mensajería de código abierto
En otro caso, cuando hay demasiadas particiones, como se muestra en la figura siguiente, cuando
[Arquitectura del sistema] Hable sobre la arquitectura y los principios del middleware de mensajería de código abierto
la carga depende en gran medida de los mensajes centrales, los requisitos para el intermediario del servidor siguen siendo relativamente altos. Después de todo, la cantidad de dependencia es relativamente grande. Además, si el mensaje tiene características de transmisión, puede ser Más grande, por lo que para el corredor, se requiere un disco duro de alta io y una gran memoria para el caché de página, y los cálculos reales requeridos no necesitan ser demasiado grandes.
[Arquitectura del sistema] Hable sobre la arquitectura y los principios del middleware de mensajería de código abierto

fiabilidad

La confiabilidad es una característica importante del middleware de mensajes. Veamos cómo mq transfiere estos mensajes. Primero tome activemq como referencia. Se basa en el mecanismo push & push.

¿Cómo garantizar que todos los mensajes enviados se consuman? Después de que el productor de Activemq envía un mensaje, necesita recibir un acuse de recibo del corredor para confirmar el recibo.La misma garantía también es válida para el corredor al consumidor.

El mecanismo de Metaq es el mismo, pero el corredor llega al consumidor a través de un método de extracción, por lo que su garantía de llegada depende de la capacidad del consumidor, pero en general, es poco probable que el clúster del servidor de aplicaciones tenga un efecto de avalancha.

¿Cómo asegurar la idempotencia de los mensajes? En la actualidad, básicamente ni Activemq ni Metaq pueden garantizar la idempotencia de los mensajes, lo que requiere cierto negocio para garantizarlo. Porque una vez que el corredor se agote, lo intentará nuevamente. Si lo intenta nuevamente, se generará un nuevo mensaje. Es posible que el corredor ya haya recibido el mensaje. En este caso, es imposible garantizar que la misma transacción comercial generará dos mensajes.

¿Cómo garantizar la fiabilidad del mensaje? En este punto, activemq y metaq tienen básicamente el mismo mecanismo:
Garantía del productor: Después de producir los datos, deben persistir después de llegar al corredor antes de devolver ACK al
corredor de origen . Garantía: Después de recibir el mensaje, el servidor metaq lo actualiza en el disco duro con regularidad, y luego los datos Todos se replican en el esclavo a través de síncrono / asíncrono, para garantizar que el consumo no se vea afectado después del tiempo de inactividad.
Activemq también se almacena localmente a través de la base de datos o archivos para la recuperación local.

Garantía del consumidor: el consumidor del mensaje consume el mensaje uno por uno y solo consume el siguiente mensaje después de consumir con éxito un mensaje. Si un mensaje no se puede consumir (como una excepción), intentará consumir el mensaje de nuevo (el máximo predeterminado es 5 veces). Una vez que el número máximo de veces aún no se pueda consumir, el mensaje se almacenará en el disco local del consumidor y en el hilo de fondo. Sigue intentándolo de nuevo. El hilo principal continúa retrocediendo y consume mensajes posteriores. Por lo tanto, solo después de que MessageListener confirme que un mensaje se consumió con éxito, el metaconsumidor continuará consumiendo otro mensaje. Esto asegura un consumo confiable de mensajes.

consistencia

La consistencia de mq discutimos dos escenarios:
1: para garantizar que el mensaje no se envíe / consuma varias veces

2: Garantizar transacciones
. Algunos de los mqs que acabamos de describir no pueden garantizar la coherencia. ¿Por qué no garantizar? El costo es relativamente alto. Solo se puede decir que esto se puede garantizar modificando el código fuente, y el esquema no es relativamente complicado, pero la sobrecarga adicional es relativamente grande, como asegurar un cierto período de tiempo a través de un clúster de caché adicional. Repetibilidad, creo que debería haber algo de mq con esta función más adelante.

Activemq admite dos tipos de transacciones, una es la transacción JMS y la otra es la transacción distribuida XA. Si traes una transacción, se generará un transactionId al corredor durante la interacción. El corredor implementa algunas TM para asignar el procesamiento de transacciones. Metaq también admite transacciones locales y XA, cumple con el estándar JTA Las garantías de transacción de activemq y metaq se realizan a través del método rehacer log, que es básicamente el mismo.

La transacción distribuida aquí solo está garantizada después de la fase de intermediario. El mensaje preparado se almacenará en un archivo local antes de que el intermediario se comprometa, y el mensaje se escribirá en la cola en la fase de confirmación, y finalmente la confirmación de dos fases se realiza mediante TM.

resumen

Por ejemplo, hay algunos middleware de mensajería con muy buen rendimiento dentro de la empresa, y espero que pueda ser de código abierto y utilizado por más personas en el futuro. Para algunos middleware de mensajería populares, podemos personalizar diferentes arquitecturas para diferentes aplicaciones, diferentes costos y diferentes desarrollos.Por supuesto, estas arquitecturas deben considerarse de muchas maneras.

Lectura recomendada:

Cuidadosamente organizado | El catálogo de artículos en la segunda mitad de 2017.
Soluciones viables para una fuerte coherencia entre el caché y la base de datos.
El búfer del proceso del usuario y el búfer del kernel
introducen la programación dinámica a través de historias de minas de oro (parte 1)

Céntrese en compartir resumen de conocimientos de pila de tecnología de fondo del servidor

Bienvenido a prestar atención a la comunicación y al progreso común.

[Arquitectura del sistema] Hable sobre la arquitectura y los principios del middleware de mensajería de código abierto

Codificación

¡El productor de códigos tiene la manera correcta de proporcionarle artículos técnicos fáciles de entender para facilitar la tecnología!

Supongo que te gusta

Origin blog.51cto.com/15006953/2552096
Recomendado
Clasificación