[Arquitectura del sistema] La arquitectura y el principio del middleware de mensajes

La función del middleware de mensajes es ser un proveedor de capacidades de concurrencia asíncrona, no solo eso, sino que también debe garantizar muchas capacidades en la arquitectura, alta disponibilidad, alta concurrencia, escalabilidad, confiabilidad, integridad, garantía de pedidos, etc. Esto ha causado dolores de cabeza a varios diseñadores; hay algunas necesidades anormales, como un consumo lento, no repetitivo, etc. El costo de diseño que debe gastarse es bastante alto, por lo que no superes ciegamente a Daniel de código abierto, por muchos mecanismos, casi Es necesario reconstruirlo; no es tan simple construir una nube privada que sea adecuada para todas las empresas, fácil de usar y universal.

Si un sistema de pago procesa miles de millones de pedidos comerciales todos los días, la capacidad de procesamiento del middleware de mensajes debe ser de al menos casi 10 mil millones, porque muchos sistemas dependen de la capacidad de agrupación del middleware y para garantizar que no se puedan cometer errores, entonces Analicemos un poco el middleware de algunos aspectos de la arquitectura.

Alta disponibilidad (alta disponibilidad)

La alta disponibilidad es un tema eterno. Esto también es una medida de confiabilidad en el mundo financiero. Debe saber que los arquitectos en la industria financiera encontrarán formas de prevenir la pérdida de datos, incluso si se trata de datos, pero de hecho, esto En teoría, depende del personaje. . . Esto no es un parpadeo.

Para dar un ejemplo, en la arquitectura de datos de Internet, al menos tres copias de los datos se llaman altas garantías, pero de hecho, el centro de datos belga de Google perdió permanentemente 0.00001% después de ser alcanzado por un rayo en 8.13, menos de 0.05 % De los discos no han sido reparados. Lo que quiero decir aquí es que es el momento adecuado y la situación es muy importante. No hay nada imposible en condiciones extremas, habrá vulnerabilidades arquitectónicas. Echemos un vistazo a la práctica general de alta disponibilidad de mq:

La siguiente figura es la solución HA de activemq:

1233356-702eb3dea716f13b.png

La HA de Activemq se aloja a través de la conmutación por error maestro / esclavo, donde el interruptor maestro-esclavo se puede cambiar de varias maneras:

1: Use un nfs u otro dispositivo de disco compartido para realizar un bloqueo compartido. Marque el estado del maestro al ocupar el bloqueo del archivo compartido. Cuando m cuelga, el esclavo correspondiente ocupará el bloqueo compartido y se convertirá en maestro

2: La gestión del clúster a través de zookeeper es más común y no se describirá aquí.

La siguiente figura es la solución HA de metaq

1233356-a908be28c6cd391e.png

Como se muestra en la figura anterior, lo mismo es cierto para los nodos maestro y esclavo que administran intermediarios a través de zk.

Por supuesto, este es solo uno de los mecanismos de conmutación por error. Solo puede garantizar que el mensaje se convierta en esclavo cuando el agente cuelga, pero no puede garantizar la pérdida del mensaje en el medio del proceso.

Cuando el mensaje fluye del intermediario, es probable que sea causado por un tiempo de inactividad u otra falla de hardware, lo que puede hacer que se pierda el mensaje. En este momento, se necesita 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 del almacenamiento no solo requiere una velocidad rápida, sino que también requiere un costo muy bajo de los requisitos de E / S. Kafka ha diseñado un conjunto de mecanismos de almacenamiento para cumplir con los requisitos anteriores. Aquí es simple Introducir

Primero, el tema en kafka se divide en múltiples particiones en una implementación distribuida. La partición es equivalente a una carga en el mensaje, y luego el enrutamiento es realizado 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. . . Espere N particiones, cada partición generará un directorio local como / debit_account_msg / topic

El archivo en el interior se dividirá en muchos segmentos, cada segmento definirá un tamaño, como un segmento de 500 MB, un archivo se divide en dos partes de índice y registro

    00000000000000000.index
    00000000000000000.log
    00000000000065535.index
    00000000000065535.log

El número representa el punto de partida del índice del valor de msgId, y la estructura de datos correspondiente es la siguiente:

1233356-972f90ede17eaaa8.png

1,0 representa el mensaje con msgId de 1, y 0 representa el desplazamiento en este archivo. Después de leer este archivo, busque el archivo de registro de segmento correspondiente y lea la información de mensaje correspondiente. La información correspondiente es fija Formato del cuerpo del mensaje:

1233356-cbdd6229fc1c0ea4.png

Obviamente, la simple aplicación de este mecanismo es definitivamente incapaz de cumplir con el alto IO concurrente, primero busca el binario del archivo de segmento, luego encuentra los datos correspondientes a través del desplazamiento, luego lee el tamaño del mensaje, luego lee el cuerpo del informe, al menos 4 veces el disco io, la sobrecarga es relativamente grande Pero la lectura secuencial utilizada al tirar, básicamente tiene poco efecto.

Además de la consulta anterior. De hecho, antes de escribir en el disco, se leen y escriben en el caché de página en el sistema operativo, y luego el disco duro se vacía (estrategia LRU) a través de subprocesos asincrónicos, pero este riesgo es realmente muy grande, porque una vez que el sistema operativo falla, causará La pérdida de datos, especialmente en el caso del consumo lento y la acumulación de muchos datos, pero el metaq más joven de Kafka ha realizado muchos cambios en esta pieza, y el mecanismo de replicación de estos archivos de partición (utilizados por Ali), así que a este nivel Las posibilidades de perder mensajes debido a la caída de rayos en Internet serán relativamente pequeñas. Por supuesto, no descarta lo que sucede cuando se cava el cable óptico en la sala de host.

Dicho esto, parece ser más perfecto y hermoso, pero de hecho, el costo de operación y mantenimiento parece ser muy alto. Debido a que estos son archivos, una vez que se produce un problema, es bastante problemático manejarlo manualmente, y está en una sola máquina, y requiere costos de operación y mantenimiento relativamente grandes para realizar algunas especificaciones de operación y mantenimiento e instalaciones de llamadas API.

Entonces, en esta área, podemos transformar y almacenar datos en algunos nosql, como mongoDB, por supuesto, mysql también es posible, pero las capacidades io y nosqldb no están en el mismo nivel, a menos que tengamos un mecanismo de procesamiento de transacciones sólido y financiero Li es bastante estricto con este requisito. Como el uso de metaq 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 que usaban mq se usaban para resolver el problema de la 性能suma 异步化. De hecho, para el mismo punto, uno io调度no consume tantos recursos. Sin más preámbulos, veamos algunos de los puntos de alta concurrencia en mq. Aquí hay algunos fondos famosos de middleware:

Activemq era una solución de nivel empresarial especializada en ese momento. Cumplía con la especificación jms en jee. De hecho, el rendimiento seguía siendo bueno, pero cuando fue llevado a Internet, era un conejo con una sandía, y no había nada que pudiera hacer.

Rabbitmq está escrito en lenguaje erlang, cumple con la especificación del protocolo AMQP y es más multiplataforma. El modo de transferencia de modo debe ser más rico y distribuido en

rocketmq (la última versión de metaq3.0 hoy, kafka es también el predecesor de metaq, inicialmente se vinculó en un sistema de mensajes de registro de código abierto), metaq básicamente escribió el principio y el mecanismo de kafka en java, después de muchas transformaciones, transacciones de soporte, La velocidad de desarrollo es muy rápida, y hay muy buenas comunidades en Ali y China para hacer este mantenimiento.

Para la comparación del rendimiento, aquí hay algunos datos de Internet solo como referencia:

1233356-9db0160ceb800c69.png

Para ser sincero, en estos niveles de datos, la diferencia no es demasiado ridícula, pero podemos analizar algunos puntos en común, ¿cuáles son las principales diferencias de rendimiento?

Rocketmq es el sucesor de metaq. Excepto por las mejoras en algunas características y mecanismos nuevos, los principios de rendimiento son similares. Estos son algunos aspectos destacados de estos altos rendimientos:

El consumo de rocketmq utiliza principalmente el mecanismo de extracción, por lo que para el corredor, muchas características de consumo no necesitan implementarse en el corredor, solo necesitan extraer los datos relevantes a través del consumidor, y como activemq, rabbitmq son más antiguos La forma de permitir que los corredores envíen mensajes, por supuesto, estos también son algunos métodos de entrega estándar de jms o amqp

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

pagecacheUn consumo en caliente se logra al golpear los datos en el caché del sistema operativo.

El IO de disco por lotes y el IO de red de metaq intentan que los datos se ejecuten en un io, y los mensajes están todos en lotes, por lo que la programación de io no necesita consumir demasiados recursos.

Transmisión de NIO, como se muestra a continuación, esta es una arquitectura del metaq original. El metaq original utilizó algunos marcos de NIO de alto rendimiento integrados con el gecko interno de Taobao y la notificación remota para distribuir mensajes:

1233356-fbc7dcdd0ded3c5d.png

El peso ligero de la cola del consumidor, debemos saber que nuestras capacidades de mensaje se obtienen a través de la cola

Mira la imagen de abajo:

1233356-dde4266c8cd62300.png

metaq cola de la cola de la lógica de consumo agregado físicamente, la cola correspondiente a los datos del disco es de serie, no se añadirá a la cola para añadir discos iowaitcarga, se puede escribir de forma secuencial, pero cuando la lectura es todavía una necesidad de leer el azar primero es la cola lógica, y después lee el disco, por lo pagecacheque es importante tratar de hacer una gran cantidad de memoria, esta asignación será utilizado plenamente.

De hecho, lo anterior básicamente puede garantizar nuestro rendimiento a un nivel relativamente alto; pero a veces el rendimiento no es lo más importante, lo más importante es hacer un equilibrio óptimo con otras características arquitectónicas, después de todo, hay Otros mecanismos deben ser satisfechos. Esto se debe a que los tres problemas más difíciles en la industria son: alta concurrencia, alta disponibilidad y consistencia.

Escalable

Esta es una pregunta común: para sistemas generales o middleware, puede expandirse mejor, pero en el middleware de mensajes, siempre ha sido una molestia. ¿Por qué?

Permítanme hablar acerca de las limitaciones de la expansión de activemq primero, porque la expansión de activemq requiere la naturaleza del negocio. Como agente, 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 juega la carga:

1233356-b24977e544400a1d.png

Suponemos que el productor envía mensajes de tema A. Si todos los consumidores están conectados a cada corredor en circunstancias normales, ¿está caliente? Si hay un mensaje del productor en el corredor, puede transferirse al consumidor correspondiente.

Pero si no hay un mensajera correspondiente en broker2 en la figura, ¿qué debemos hacer en este caso? Debido a que se supone que hay muchos nodos del sistema de aplicación (productor) y del sistema dependiente (consumidor) del mismo tema, ¿cómo ampliar la capacidad? Activemq puede hacer la parte normal de la imagen de arriba, pero necesita cambiar la configuración correspondiente de productor, corredor, consumidor, lo cual es bastante problemático.

Por supuesto, activemq también puede realizar búsquedas dinámicas a través de multidifusión (alguien mencionó que lvs o f5 se usa como carga, pero hay un gran problema para los consumidores, y esta configuración de carga no tiene un efecto sustancial en la distribución del tema) Sin embargo, todavía habrá el problema que dije. Si el tema es demasiado grande, cada corredor necesita conectar a todos los productores o consumidores, de lo contrario, aparecerá la situación que dije y la expansión de activemq es bastante problemática en este sentido.

Hablemos sobre cómo metaq hace esto, mira la imagen y habla:

1233356-888ca116dff81d84.png

Metaq está dividido por tema. En este nivel, solo necesitamos configurar tantas particiones de tema como sea posible. De esta manera, la división es tener un concepto de "negocio" como regla de enrutamiento; en general, hay muchas configuraciones en una máquina de intermediario. Tema, cada tema generalmente tiene solo una partición en una máquina, si la máquina no es suficiente, también puede admitir múltiples particiones, en general, podemos usar la identificación de negocios para modelar particiones personalizadas, obteniendo los parámetros del área de envío Eso es todo

1233356-53305f2951166b6d.png
1233356-8b0c266b9ca55e6d.png

Fiabilidad

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

¿Cómo asegurar que se consuma cada mensaje enviado? Los productores de Activemq deben recibir el reconocimiento de un corredor después de enviar un mensaje para confirmar el recibo. La misma garantía también se brinda a los corredores para los consumidores.

El mecanismo de Metaq también es el mismo, pero el intermediario para el consumidor se retira, 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 garantizar la idempotencia del mensaje? En la actualidad, básicamente activemq, metaq no puede garantizar la idempotencia del mensaje, lo que requiere algunas empresas para garantizar. Porque una vez que el corredor agota el tiempo de espera, se volverá a intentar, y si se vuelve a intentar, se generarán nuevos mensajes. Es posible que el corredor haya aterrizado, por lo que en este caso, no hay garantía de que la misma cartera de negocios produzca 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 datos para el corredor, se debe persistir para devolver ACK

Garantía del agente: después de que el servidor metaq recibe el mensaje, lo actualiza regularmente en el disco duro y luego los datos se copian 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 una base de datos o archivo para realizar una recuperación local

Garantía del consumidor: los consumidores de mensajes consumen mensajes uno tras otro, solo después de consumir con éxito un mensaje continuarán consumiendo el siguiente. Si no puede consumir un mensaje (como una excepción), intentará consumir el mensaje nuevamente (el máximo es 5 veces por defecto). Después de exceder el número máximo de veces, aún no se puede consumir, y el mensaje se almacena en el disco local del consumidor, que está respaldado por un hilo de fondo. Continúa intentando de nuevo. El hilo principal continúa yendo hacia atrás, consumiendo mensajes posteriores. Por lo tanto, solo después de que MessageListener confirme el consumo exitoso de un mensaje, el metaconsumidor continuará consumiendo otro mensaje. Esto asegura el consumo confiable de mensajes.

Consistencia

La consistencia de mq discutimos dos escenarios:

1: Garantizar que el mensaje no se enviará / consumirá varias veces
2: Garantía de transacción

Algunos de los mq introducidos anteriormente no pueden garantizar la coherencia, entonces, ¿por qué no? El costo es relativamente alto, solo se puede decir que esto puede garantizarse modificando el código fuente, y el esquema es relativamente no demasiado complicado, pero la sobrecarga adicional es relativamente grande, como a través de un clúster de caché adicional para garantizar un cierto período de tiempo. Repetibilidad, creo que debería haber algo de mq con esta función.

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

La transacción distribuida aquí solo se garantiza después de la etapa de intermediario. Antes de que el intermediario se comprometa, el mensaje de preparación se almacenará en el archivo local y el mensaje se escribirá en la cola hasta la etapa de confirmación. Finalmente, la confirmación de la segunda etapa se implementa a través de TM.


Comunidad de desarrolladores de Kotlin

1233356-4cc10b922a41aa80

La cuenta pública de la primera comunidad de desarrolladores de Kotlin en China, que comparte e intercambia principalmente temas relacionados, como el lenguaje de programación Kotlin, Spring Boot, Android, React.js / Node.js, programación funcional e ideas de programación.

Cuanto más ruidoso es el mundo, más pensamiento pacífico se necesita.

1665 artículos originales publicados · 1067 elogiados · 750,000 vistas

Supongo que te gusta

Origin blog.csdn.net/universsky2015/article/details/105531346
Recomendado
Clasificación