RocketMQ - Cómo implementar mensajes secuenciales
Escenarios para usar mensajes secuenciales
En proyectos diarios, hay muchos escenarios que necesitan garantizar la secuencia, por ejemplo, creación de pedidos, pago y reembolso en escenarios transaccionales, creación de pedidos. El pago puede solo se realizará después de realizar el pago, y los reembolsos solo se emitirán para pedidos pagados, lo que requiere una garantía de primero en entrar, primero en salir (FIFO). Otro ejemplo es el mensaje BinLog de la base de datos. Cuando la base de datos ejecuta una declaración de adición o una declaración de modificación, el mensaje BinLog obtenido para la orden también debe garantizar que sea un mensaje de adición o un mensaje de modificación.
Cómo enviar y consumir mensajes secuenciales
Utilizamos mensajes secuenciales RocketMQ para simular escenarios de pedidos, que se dividen en dos partes: envío secuencial y consumo secuencial.
1. Envío secuencial
El código anterior simula el envío de mensajes de creación, pago y reembolso a TopicTest en secuencia. En el archivo de configuración application.properties, especifique productor.sync=true para enviar mensajes de forma asincrónica de forma predeterminada y cámbielo a sincrónico aquí.
MessageBuilder establece el encabezado del mensaje Header para indicar que se trata de un mensaje secuencial y envía el mensaje a la cola de mensajes número 0.
2. Reciba mensajes en orden
Después de ejecutar el programa, puede ver la salida del registro en la consola, que también se imprime en orden
En orden Principios técnicos del envío
La entrega secuencial de mensajes en RocketMQ se divide en dos situaciones: pedido local y pedido global. El ejemplo anterior es el caso de los pedidos locales.
Hay tres formas de enviar mensajes en RocketMQ: sincrónico, asincrónico y de punto único.
El principio del envío secuencial de mensajes es simple: los mensajes del mismo tipo se envían a la misma cola. Para garantizar que el primer mensaje enviado se almacene primero en la cola de mensajes, debe utilizar el envío sincrónico; de lo contrario, puede enviarlo a la cola de mensajes después del primer mensaje, momento en el cual se alterará el orden de los mensajes.
El código central de RocketMQ es el siguiente:
El proceso de selección de cola se completa mediante messageQueueSelector y hashKey en la clase de implementación SelectMessageQueueByHash
En el proceso Para obtener la lista de colas, Productor La cola se consulta desde el NameServer para consultar la lista de Broker según el Tema. La lista se almacena en caché en la memoria local para que pueda leerse desde el caché la próxima vez.
Principios técnicos del envío ordinario
Además de admitir mensajes secuenciales, RocketMQ también admite mensajes de transacciones y mensajes retrasados. Los mensajes que no pertenecen a estas tres características se denominan mensajes ordinarios. Los mensajes ordinarios se utilizan con mayor frecuencia en el desarrollo diario, porque los escenarios de aplicación más comunes son el desacoplamiento asincrónico del sistema y el tráfico de pico a pico. Estos escenarios de aplicación intentan garantizar un alto rendimiento en el envío y recepción de mensajes.
A partir de la comparación de mensajes normales y mensajes secuenciales, se utilizan diferentes estrategias de selección de colas de mensajes para enviar mensajes normales. Hay dos mecanismos para seleccionar una cola de envío de mensajes normal: mecanismo de sondeo y mecanismo para evitar fallas. Por defecto se utiliza un mecanismo de sondeo. Un tema tiene varias colas y el sondeo seleccionará una de ellas.
El principio del mecanismo de sondeo es que la información de enrutamiento TopicPublishInfo mantiene un contador sendWhichQueue. Cada vez que se envía un mensaje, se debe consultar la ruta. La calculadora será "1" y se calculará el modelo. según el valor del índice del contador y el número de colas para implementar el algoritmo de sondeo. El algoritmo de sondeo se implementa modelando el índice de valor del contador y el número de colas.
El algoritmo de sondeo es simple y fácil de usar, pero también tiene desventajas. Si la cola seleccionada por el sondeo está en un Broker caído, la entrega del mensaje fallará incluso si se envía. y se vuelve a seleccionar la cola, es posible que todavía esté en la cola. En un Broker caído, la falla de entrega no se puede evitar, por lo que existe un mecanismo para evitar fallas.
Principios técnicos del consumo secuencial
RocketMQ admite dos modos de consumo: consumo de clúster y consumo de transmisión. La diferencia entre estos dos modos de consumo es que en el modo de consumo de transmisión, cada mensaje es consumido por cada consumidor en ConsumerGroup, mientras que en el modo de consumo en clúster, cada mensaje es consumido por solo un consumidor en ConsumerGroup.
La mayoría de los escenarios de aplicaciones utilizan el consumo de clúster, donde cada consumo de un mensaje representa un proceso comercial, y el consumo de clúster significa que cada mensaje es procesado por cualquier instancia de servicio en el clúster de aplicaciones comerciales. Algunos escenarios de aplicaciones utilizan el consumo de transmisión. Por ejemplo, los cambios de datos actualizarán el caché local de cada servicio en el clúster de aplicaciones comerciales, lo que requiere que todo el clúster consuma el mensaje una vez;
El consumo secuencial también se denomina consumo ordenado. El principio es que la misma cola de mensajes solo permite que un hilo de consumidor en el consumidor extraiga y consuma, y el consumidor tiene un grupo de hilos de consumidor y varios hilos lo harán. consumirse simultáneamente. En el escenario de consumo secuencial, el hilo consumidor solicita al Broker que solicite un bloqueo exclusivo y la solicitud para obtener el bloqueo permite el consumo.
Después de que el mensaje se consuma exitosamente, el progreso del consumo se enviará al Broker para actualizar la información del bit de consumo y evitar extraer el siguiente mensaje consumido durante el consumo secuencial, si el hilo consumidor está realizando el procesamiento comercial. El oyente lanzará una excepción, el progreso del consumo no se enviará, el progreso del consumo se bloqueará en el mensaje actual y los mensajes posteriores en la cola no continuarán consumiéndose, lo que garantiza el consumo secuencial.
En escenarios de consumo secuencial, es particularmente importante prestar atención al manejo de excepciones. Si el reintento falla, el mensaje actual se bloqueará hasta que se exceda el número máximo de reintentos, lo que resultará en la imposibilidad de consumir mensajes posteriores durante mucho tiempo, lo que provocará que la cola se llene de mensajes.
Principios del consumo concurrente
RocketMQ admite dos métodos de consumo: consumo secuencial y consumo concurrente. El consumo concurrente es el método de consumo predeterminado y el método más utilizado en el desarrollo diario, excepto el consumo secuencial.
El consumo concurrente también se denomina consumo secuencial. El principio es que en un consumidor, varios subprocesos del consumidor pueden extraer y consumir la misma cola de mensajes. y consumir mensajes de la misma cola de mensajes simultáneamente. Si un subproceso de consumidor genera una excepción mientras realiza el procesamiento comercial en el oyente, el subproceso actual lo volverá a intentar sin afectar el progreso de consumo de otros subprocesos de consumidor y colas de consumo, y los subprocesos que consumen mensajes con éxito enviarán su progreso de consumo normalmente.
El consumo concurrente es mucho más rápido que el consumo secuencial porque no hay contención de recursos durante el proceso de bloqueo.
Inercia de mensajes
Hablando de consumo de mensajes, tenemos que mencionar la inercia de mensajes. El código comercial generalmente solo recibe un mensaje una vez para el procesamiento de la lógica comercial. Entonces, si el mismo mensaje se recibe varias veces, ¿dará lugar a un procesamiento comercial repetido?
RocketMQ no garantiza que los mensajes no se consumirán repetidamente. Si la empresa es muy sensible al consumo repetido de mensajes, la pereza debe manejarse a nivel empresarial, lo que se puede lograr mediante el bloqueo distribuido.
En todos los sistemas de mensajería, existen tres modos de consumo de mensajes: consumo como máximo una vez, consumo al menos una vez y consumo exactamente una vez. Los sistemas de mensajería distribuida logran un equilibrio entre estos tres modos, y los dos primeros son viables y ampliamente utilizados.