10,000 palabras lo llevarán a través de RocketMQ

prefacio

Las colas de mensajes se utilizan en muchos escenarios en el trabajo. En pocas palabras, las colas de mensajes son  contenedores para almacenar mensajes durante la transmisión de mensajes . La cola de mensajes resuelve principalmente problemas como el acoplamiento de aplicaciones, el procesamiento asincrónico y la reducción de los picos de tráfico. Hoy echaremos un vistazo a RocketMQ, un producto de código abierto de Ali  .

Introducción a RocketMQ

RocketMQ es un middleware de mensajes distribuidos con baja latencia, alta concurrencia, alta disponibilidad y alta confiabilidad. Con las ventajas de la comunicación asíncrona, la topología del sistema es simple y el acoplamiento ascendente y descendente es débil. Se utiliza principalmente en escenarios como el desacoplamiento asíncrono, el afeitado de picos de tráfico y el llenado de valles.

Nombre del servidor

NameServer es el "cerebro" de todo RocketMQ y  el centro de enrutamiento de RocketMQ . La función principal de NameServer es proporcionar información de enrutamiento sobre temas para productores y consumidores de mensajes , por lo que NameServer necesita almacenar información de enrutamiento y poder administrar los nodos de Broker, incluido el registro de enrutamiento, la eliminación de enrutamiento y otras funciones.

Alta disponibilidad del centro de enrutamiento

Una vez que el "cerebro" funciona mal, no es broma y debe haber contramedidas para resolverlo. Se puede lograr una alta disponibilidad de NameServer  mediante la implementación de varios servidores de NameServer , pero no se comunican entre sí. Aunque los datos entre los servidores de NameServer no serán exactamente iguales en un momento determinado, no tendrá un gran impacto en el envío de mensajes, no es más que un desequilibrio a corto plazo en el envío de mensajes (¿tiene un sabor familiar? Sí , teoría CAP, no es esto solo AP). RocketMQ eligió AP en el diseño del módulo NameServer.

almacenamiento de metadatos

Dado que es un centro de enrutamiento, ¿cómo se almacena la información de enrutamiento? Echemos un vistazo a la clase RouteInfoManager.

public class RouteInfoManager {
    // Topic消息队列的路由信息
    private final HashMap<String/* topic */, List<QueueData>> topicQueueTable;
    // Broker的基础信息
    private final HashMap<String/* brokerName */, BrokerData> brokerAddrTable;
    // Broker的集群信息
    private final HashMap<String/* clusterName */, Set<String/* brokerName */>> clusterAddrTable;
    // Broker的状态信息,NameServer每次收到心跳包时会替换该信息
    private final HashMap<String/* brokerAddr */, BrokerLiveInfo> brokerLiveTable;
    // Broker对应的FilterServer列表,用于类模式消息过滤。类模式过滤机制在4.4及以后版本被废弃
    private final HashMap<String/* brokerAddr */, List<String>/* Filter Server */> filterServerTable;
}

La información almacenada por NameServer está en la clase RouteInfoManager.

registro de ruta

El registro de rutas RockerMQ se realiza a través de la función de latido de Broker y NameServer . Cuando el Broker se inicia, envía una declaración de latido a todos los NameServers en el clúster y envía un paquete de latido a todos los NameServers en el clúster cada 30. Después de recibir el paquete de latido, el NameServer primero actualizará el lastUpdateTimestamp de BrokerLiveInfo en el brokerLiveTable en la clase RouteInfoManager, y luego escanear el brokerLiveTable cada 10 s, si el paquete de latido no se recibe durante 120 segundos, NameServer eliminará la información de enrutamiento del Broker y cerrará la conexión del Socket al mismo tiempo.

borrado de ruta

Se mencionó anteriormente que si el servidor de nombres no recibe el paquete de latidos del corredor durante 120 segundos seguidos, eliminará la información de enrutamiento del corredor. Otro punto es que Broker  ejecutará el comando unregisterBroker cuando se cierre normalmente .

descubrimiento de ruta

El descubrimiento de rutas de RockerMQ  no es en tiempo real. Cuando la ruta del tema cambia, el servidor de nombres no la empujará activamente al cliente, pero el cliente extraerá periódicamente la ruta más reciente del tema .

Diseño de la arquitectura del servidor de nombres

Corredor

Broker se ha mencionado muchas veces anteriormente. Broker es un componente central de RocketMQ. La mayor parte del trabajo pesado se realiza a través de Broker. Borker procesa varias solicitudes y almacena mensajes, y determina el rendimiento, la confiabilidad y la disponibilidad de todo el sistema RocketMQ .

Archivo de registro de confirmación

RocketMQ busca la última escritura secuencial en disco en el proceso de escritura de mensajes, y todos los mensajes de tema se escriben en un archivo, que es el archivo CommitLog . Todos los mensajes se escriben en el archivo CommitLog secuencialmente en el orden de llegada. Una vez que se escribe un mensaje, no admite modificaciones.

Cada escritura introducirá un indicador de identidad, que es  el desplazamiento físico del mensaje (el mensaje se almacena al principio del archivo). Los archivos de CommitLog se nombran de una manera muy complicada, utilizando el desplazamiento dentro de todo el grupo de archivos de CommitLog del primer mensaje almacenado en el archivo. La ventaja de esto es que dada la compensación física de cualquier mensaje, puede buscar a través del método binario para ubicar rápidamente la ubicación del archivo y luego restar el nombre del archivo de la compensación física del mensaje, y la diferencia es Dirección absoluta en el archivo.

Archivo de cola de consumo

Todos los mensajes de temas se escriben en el archivo CommitLog. No es una buena idea recuperar mensajes del archivo CommitLog según el tema. Para resolver el problema de recuperación de mensajes basados ​​en temas, RocketMQ presenta el archivo ConsumeQueue . En pocas palabras, el archivo ConsumeQueue es el archivo CommitLog basado en el archivo de índice de temas.

La longitud de cada entrada en ConsumeQueue  es fija (desplazamiento físico de CommitLog de 8 bytes, longitud de mensaje de 4 bytes y código hash de etiqueta de 8 bytes). La ventaja de la longitud fija es que la entrada se puede ubicar rápidamente accediendo a una matriz similar subíndices, lo que mejoró en gran medida el rendimiento de lectura de los archivos ConsumeQueue.

archivo de índice

El archivo ConsumeQueue resuelve el problema de encontrar mensajes basados ​​en el tema, si desea buscar en función de un determinado atributo del mensaje, necesita que aparezca el archivo de índice.

Los archivos de índice implementan índices hash basados ​​en archivos de disco físico. El archivo de índice consta de un encabezado de archivo de 40 bytes, 5 millones de ranuras hash y 20 millones de entradas de índice. Cada ranura hash tiene 4 bytes y cada entrada de índice contiene 20 bytes (el código hash de clave de índice de 4 bytes, desplazamiento físico, marca de tiempo de 4 bytes, entrada de índice anterior de 4 bytes).

mapa de memoria

Aunque la escritura secuencial mejora en gran medida la eficiencia de E/S, el almacenamiento basado en archivos utiliza las API de operación de archivos de Java convencionales, y la mejora del rendimiento será limitada, por lo que RockerMQ presenta el mapeo de memoria . El archivo del disco se asigna a la memoria, y el disco se opera de la misma manera que la memoria ( la caché de página del sistema operativo se usa en el servidor Linux ), y se ha mejorado el rendimiento.

estrategia de pincel

La introducción del mecanismo de mapeo de memoria y caché de página garantiza en gran medida el rendimiento de escritura de RocketMQ, pero surge otro problema.Después de que el bróker recibe el mensaje enviado por el cliente, devuelve éxito después de almacenarlo en el caché de página, o ¿Ha tenido éxito? persistir en el disco? RocketMQ proporciona cepillado síncrono y cepillado asíncrono .

  • Parpadeo sincrónico : el parpadeo sincrónico significa que el éxito se devuelve al cliente solo después de que la persistencia sea exitosa. a expensas del rendimiento de escritura.
  • Descarga asincrónica del disco : La descarga asincrónica del disco significa que el bróker devuelve el éxito inmediatamente después de almacenar el mensaje en la memoria caché de la página y luego inicia un subproceso asíncrono para escribir los datos en la memoria en el disco a intervalos regulares. El intervalo predeterminado es de 500 ms.

Los mensajes se escriben en la memoria caché de la página y se leen de la memoria caché de la página cuando se consumen los mensajes. La presión sigue siendo relativamente alta cuando la concurrencia es alta. Para reducir la presión de la memoria caché de la página, RocketMQ introduce el mecanismo transientStorePoolEnable, que es un mecanismo de separación de lectura y escritura a nivel de memoria .

Mecanismo de separación de lectura y escritura a nivel de memoria : a través del mecanismo transientStorePoolEnable, RocketMQ primero escribe el mensaje en la memoria fuera del montón y lo devuelve inmediatamente, luego envía de forma asíncrona los datos en la memoria fuera del montón a la caché de la página y luego vacía de forma asíncrona los datos para la persistencia. Cuando se consume el mensaje, todavía se lee desde la memoria caché de la página, lo que forma la separación de lectura y escritura a nivel de memoria. La desventaja de este mecanismo es que los datos en la memoria fuera del montón se perderán si el Broker se cierra de manera anormal .

Corredor de alta disponibilidad

Para mejorar la alta disponibilidad del consumo de mensajes y evitar el punto único de falla de Broker, para que los mensajes almacenados en Broker no se consuman a tiempo, RocketMQ presenta el  mecanismo de sincronización maestro-esclavo de Broker . Es decir, después de que el mensaje llega al servidor maestro, el mensaje debe sincronizarse con el servidor esclavo de mensajes.Si el agente del servidor maestro está inactivo, el consumidor de mensajes puede extraer el mensaje del servidor esclavo.

Tema

El contenedor de nivel superior para la transmisión y el almacenamiento de mensajes en RocketMQ se utiliza para identificar mensajes del mismo tipo de lógica comercial. Los temas se identifican y diferencian de forma única por TopicName.

Etiquetas

Las etiquetas son un atributo de clasificación de mensajes detallado proporcionado por RocketMQ, que se puede subdividir en el nivel de tema. Los consumidores pueden lograr un filtrado detallado suscribiéndose a etiquetas específicas.

Productor

Un productor es una entidad en ejecución en el sistema RocketMQ que se utiliza para construir y transmitir mensajes al servidor. El productor generalmente está integrado en el sistema comercial, encapsula los mensajes comerciales en mensajes según sea necesario y los envía al servidor.

enviar mensaje

RocketMQ admite tres métodos de envío de mensajes: síncrono, asíncrono y unidireccional.

  • Sincronización (sync): cuando el remitente ejecuta la API del mensaje a RocketMQ, espera sincrónicamente hasta que el servidor de mensajes devuelve el resultado del envío.
  • Asíncrono (asincrónico): cuando el remitente ejecuta la API de envío de mensajes a RocketMQ, especifica la función de devolución de llamada después de que el mensaje se envía correctamente y regresa inmediatamente después de llamar a la API de envío de mensajes. operación, y el mensaje se envía con éxito o falla.La tarea se ejecuta en un nuevo hilo.
  • Unidireccional (one way): Cuando el remitente ejecuta la API de mensajes a RocketMQ, regresa directamente, sin esperar el resultado del servidor de mensajes ni registrar una función de devolución de llamada.

Alta disponibilidad de envío de mensajes

Para lograr una alta disponibilidad en el envío de mensajes, RocketMQ tiene dos características muy importantes.

  • Mecanismo de reintento de envío de mensajes : si hay un error al enviar un mensaje, se reintentará dos veces por defecto.
  • Mecanismo para evitar fallas : cuando un mensaje no se envía por primera vez, si el siguiente mensaje aún se envía al Broker que acaba de fallar, existe una alta probabilidad de que aún falle. , intentará evitar el mensaje que acaba de recibir cuando vuelva a intentarlo El Broker falló, pero elige la cola en otros Brokers para enviar.

De forma predeterminada, RocketMQ utiliza un algoritmo de turno rotativo para enrutar el equilibrio de carga . Admite algoritmos de balanceo de carga personalizados al enviar mensajes Se debe prestar especial atención al hecho de que el mecanismo de reintento de RocketMQ fallará después de usar algoritmos de carga de enrutamiento personalizados .

SendResult send(final Message msg, final MessageQueueSelector selector, final Object arg)
    throws MQClientException, RemotingException, MQBrokerException, InterruptedException;

Este es un método de selección de cola personalizado en MQProducer.El parámetro MessageQueueSelector selector de cola de mensajes puede seleccionar la cola a la que se envía el mensaje personalizado.

proceso de envío de mensajes

Consumidor

Un consumidor es una entidad en ejecución que se utiliza para recibir y procesar mensajes en RocketMQ. Los consumidores generalmente están integrados en el sistema comercial, obtienen mensajes del servidor y convierten los mensajes en información comprensible para el negocio para el procesamiento de la lógica comercial.

Grupo de consumidores (ConsumerGroup)

El consumo de mensajes se lleva a cabo en modo grupal, y un grupo de consumidores es un grupo de equilibrio de carga en el sistema RocketMQ que transporta múltiples consumidores con comportamientos de consumo consistentes. En RocketMQ, la expansión horizontal del rendimiento de consumo y la recuperación ante desastres de alta disponibilidad se realizan mediante la inicialización de múltiples consumidores en el grupo de consumidores .

Un consumidor puede contener varios consumidores y cada grupo de consumidores puede suscribirse a varios temas .

patrón de consumo

Hay dos modos de consumo entre los grupos de consumidores de RocketMQ: el modo de clúster y el modo de transmisión.

  • Modo de clúster : el mismo mensaje en el tema actual solo puede ser consumido por uno de los consumidores.
  • Modo de difusión : el mismo mensaje del tema actual será consumido una vez por todos los consumidores del clúster.

En el modo de clúster, si varios consumidores necesitan cargar la cola de mensajes, el mecanismo de carga sigue una idea general: una cola de mensajes solo puede ser consumida por un consumidor a la vez, y un consumidor puede consumir varias colas de mensajes .

mensajería

Hay dos formas de enviar mensajes entre el servidor de mensajes de RocketMQ y los consumidores: modo push y modo pull.

  • Modo de inserción : el modo de inserción consiste en que, una vez que el mensaje llega al servidor de mensajes, se envía al consumidor de mensajes.
  • Modo de extracción : es una solicitud del consumidor para iniciar un mensaje de extracción.

El modo de inserción de mensajes de RocketMQ se basa en el modo de extracción, que envuelve una capa en el modo de extracción e inicia la siguiente tarea de extracción después de que se completa una tarea de extracción. Es decir, RocketMQ no implementa realmente el modo push, pero los consumidores extraen mensajes activamente del servidor de mensajes.

Si el consumidor de mensajes envía una solicitud de extracción al servidor de mensajes, pero el mensaje no llega a la cola de mensajes y el mecanismo de sondeo largo no está habilitado, esperará un período de tiempo (suspendido) en el lado del servidor antes de juzgar si el mensaje ha llegado a la cola. Si el mensaje no ha llegado, le indicará que extraiga el cliente PULL_NOT_FOUND (el mensaje no existe). Si el modo de sondeo largo está habilitado, RocketMQ sondeará cada 5 segundos para verificar si el mensaje es accesible. Al mismo tiempo , cuando llegue un nuevo mensaje, notifique inmediatamente al hilo suspendido para verificar si el nuevo mensaje es de su interés nuevamente. En caso afirmativo, extraiga el mensaje del archivo CommitLog y devuélvalo al cliente de extracción de mensajes; de lo contrario, la suspensión expirará. , y el tiempo de espera será encapsulado por el extractor de mensajes al extraer el mensaje En la solicitud y los parámetros, el modo de inserción predeterminado es de 15 s.

Los patrones de consumo

RocketMQ admite dos modos de consumo: consumo concurrente y consumo secuencial.

  • Consumo concurrente : varios consumidores consumen el mismo lote de mensajes al mismo tiempo para mejorar la velocidad de procesamiento, independientemente del orden de los mensajes.
  • Consumo secuencial : se refiere al mismo tiempo, una cola tiene un solo consumo de subprocesos de consumo. La cola se bloqueará en el lado del corredor.

RocketMQ admite el consumo secuencial parcial y la cola tiene un orden natural, lo que significa que se garantiza que los mensajes en la misma cola de mensajes se consumirán en orden . Como se mencionó anteriormente, cuando los productores envían mensajes, pueden personalizar la selección de la cola, y cuando los consumidores consumen, pueden consumir secuencialmente a través de las características de la cola. Si desea realizar el consumo secuencial global de un determinado tema , puede establecer el número de colas del tema en 1. Tenga en cuenta que esto sacrificará la alta disponibilidad.

La lógica de implementación de consumo concurrente y consumo secuencial está en las dos clases de implementación ConsumeMessageConcurrentlyService y ConsumeMessageOrderlyService de la interfaz de código fuente ConsumeMessageService.Amigos interesados ​​pueden echarle un vistazo.

reintentar mensaje

El reintento de mensajes de RocketMQ se basa en el grupo de consumidores , y el nombre del tema de reintento de mensajes es %Reintentar% + nombre del grupo de consumidores. Los consumidores se suscriben automáticamente al tema al inicio y participan en la carga de la cola de mensajes del tema. Tenga en cuenta que el modo de transmisión no tiene un mecanismo de reintento de mensajes incorporado .

El número predeterminado de reintentos de RocketMQ es 16 veces, y el intervalo de reintentos predeterminado es (10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h), más de 16 veces son 2h.

mensaje cronometrado

El mensaje de sincronización  es un tipo de mensaje avanzado proporcionado por RocketMQ. Una vez que el mensaje se envía al servidor, los consumidores pueden consumirlo después de un tiempo específico. Al establecer un cierto tiempo de tiempo, se puede realizar el efecto de disparo de programación retrasada de la escena distribuida. RocketMQ no admite la programación de tiempo con precisión de tiempo arbitraria (si es compatible, inevitablemente conducirá a un gran consumo de rendimiento). El nivel de retraso del mensaje está controlado por messageDelayLevel en el lado del Broker, y el valor predeterminado es (1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h). Este grupo de números también se menciona en el reintento de mensajes anterior, y el reintento de mensajes también se realiza con la ayuda de tareas cronometradas. La versión superior de RocketMQ también comenzó a admitir el tiempo de retraso personalizado.

public class Message implements Serializable {
  。。。
  public void setDelayTimeLevel(int level) {
    this.putProperty(MessageConst.PROPERTY_DELAY_TIME_LEVEL, String.valueOf(level));
  }
)

Al enviar mensajes retrasados, solo necesita llamar al método setDelayTimeLevel en la clase Message para establecer el nivel de retraso. El valor del nivel es un valor int de 1 a 18, correspondiente a 1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h.

mensaje transaccional

Los mensajes transaccionales son un tipo de mensaje avanzado proporcionado por RocketMQ, que admite la consistencia eventual de la producción de mensajes y transacciones locales en escenarios distribuidos .

Los mensajes transaccionales ocurren entre el Productor y el Corredor. Los mensajes de transacción se implementan a través de TransactionMQProducer. Después de enviar medio mensaje a través del método sendMessageInTransaction(final Message msg, final Object arg) en la clase TransactionMQProducer, la clase de escucha se implementa de la siguiente manera.

public class MyLocalTransactionListener implements TransactionListener {
  
  @Override
  public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
      // 执行本地事务
      // 。。。
      // 返回事务状态
      return LocalTransactionState.UNKNOW;
  }
  @Override
  public LocalTransactionState checkLocalTransaction(MessageExt msg) {
      // 检查事务状态
      // 。。。
      // 返回事务状态
      return LocalTransactionState.COMMIT_MESSAGE;
  }
}

El método executeLocalTransaction se usa para ejecutar una transacción local y devolver el estado de la transacción. checkLocalTransaction se utiliza para verificar el estado de la transacción local y responder a la solicitud de verificación de la cola de mensajes.

filtrado de mensajes

RocketMQ admite dos modos de filtrado de mensajes: expresión (TAG, SQL92) y modo de filtrado de clases.

  • El modo TAG  es el modo de filtrado de mensajes más utilizado, que filtra según la etiqueta del mensaje (Tag).
  • El modo SQL92  es un modo de filtrado de mensajes más flexible. Utiliza las propiedades del mensaje para ejecutar expresiones de filtro SQL similares para la coincidencia condicional. Al enviar un mensaje, debe establecer el método putUserProperty de la propiedad del usuario para establecer la propiedad.
  • El modo de filtrado de clases  es un método de filtrado basado en el nombre de clase del consumidor y la lógica de filtrado se implementa en el lado del consumidor.

Tipo de mensaje (MessageType)

El tipo de mensaje es una clasificación definida en RocketMQ según diferentes características de transmisión de mensajes, que se utiliza para la gestión de tipos y la verificación de seguridad. Los tipos de mensajes admitidos por RocketMQ son mensajes ordinarios, mensajes secuenciales, mensajes transaccionales y mensajes de temporización.

A partir de la versión 5.0, Apache RocketMQ admite la verificación obligatoria de los tipos de mensajes, es decir, cada tema Tema solo puede enviar mensajes de un tipo de mensaje, lo que puede mantener y administrar mejor el sistema de producción y evitar confusiones. Pero al mismo tiempo, se garantiza la retrocompatibilidad con el comportamiento de la versión 4.x.La función de verificación obligatoria está deshabilitada por defecto.Se recomienda habilitar manualmente la verificación a través del parámetro del servidor enableTopicMessageTypeCheck.

Posición del mensaje (MessageQueueOffset)

Los mensajes se almacenan en varias colas de un tema específico en el orden en que llegan al servidor de RocketMQ, y cada mensaje tiene una coordenada de tipo Long única en la cola, que se define como una ubicación de mensaje . Cada consumidor de mensajes puede determinar la posición inicial de su propio consumo a través de la ubicación del mensaje. Es decir, el desplazamiento del mensaje en la cola de mensajes.

Compensación del consumidor (ConsumerOffset)

Después de que un consumidor consuma un mensaje, no se eliminará de la cola inmediatamente. RocketMQ registrará la ubicación del último mensaje consumido en función de cada grupo de consumidores, es decir, la ubicación de consumo .

private ConsumeFromWhere consumeFromWhere = ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET;

De forma predeterminada, el consumidor comienza a consumir desde la última posición. Tenga en cuenta que esta configuración solo tiene efecto cuando el consumidor se inicia por primera vez y cuando se reequilibra.

  • Para el consumo de clúster . El punto de consumo es mantenido y administrado por el servidor RocketMQ. En el modo de consumo de clúster, los consumidores del mismo grupo de consumo consumen la misma cola de mensajes juntos y cada consumidor mantiene su propio sitio de consumo de forma independiente. El servidor RocketMQ guardará la información del sitio de consumo en el lado del corredor o en el lado del servidor de nombres (diferentes versiones o diferentes configuraciones). De esta forma, en el caso de reinicio del consumidor, reequilibrio, etc., el servidor puede restaurar correctamente el progreso del consumo del consumidor.
  • Para el consumo de difusión . La ubicación de consumo es administrada por cada consumidor y almacenada en el almacenamiento local. En el modo de consumo de difusión, cada consumidor consume todos los mensajes de forma independiente, por lo que cada consumidor necesita mantener su propia ubicación de consumo. Los consumidores pueden optar por guardar la ubicación de consumo en el sistema de archivos, la base de datos u otro almacenamiento externo, y cargar la última ubicación consumida desde el almacenamiento local cuando el consumidor se inicia, y actualizar periódicamente la ubicación de consumo en el almacenamiento local.

Precauciones

  • Gestión de configuración: cada componente de RocketMQ tiene muchas configuraciones, así que asegúrese de entenderlo cuidadosamente y configurarlo correctamente antes de usarlo.
  • Número de colas: El número de colas está relacionado con el límite superior de capacidad de consumo. Una cola solo puede ser consumida por un consumidor (si un tema tiene 8 colas y se inician 10 consumidores, entonces dos consumidores están inactivos).
  • Mensaje confiable: RocketMQ es asincrónico de forma predeterminada y se puede forzar a que parpadee inmediatamente según los escenarios comerciales.
  • Grupos de consumidores: asegúrese de que los diferentes grupos de consumidores usen diferentes nombres de consumidores. Solo se configura un método de consumo para el mismo grupo de consumidores (he encontrado un grupo de consumidores con varios consumidores de clúster y varios consumidores de transmisión, y también se ha iniciado ...).
  • Orden de consumo: preste atención a si se requiere el consumo de orden de los mensajes. RocketMQ puede garantizar el consumo de orden de los mensajes en una sola cola. Si se necesita garantizar el orden de los mensajes, los mensajes relacionados se pueden enviar a la misma cola.

Supongo que te gusta

Origin blog.csdn.net/mxt51220/article/details/131700693
Recomendado
Clasificación