1. Modo de envío de mensajes
1.1 Transmisión síncrona
El modo de envío de mensajes síncronos significa que después de que se envía el mensaje, el productor esperará hasta que el corredor responda antes de continuar enviando el siguiente mensaje.
DefaultMQProducer producer = new DefaultMQProducer("my_producer_group");
producer.send(message); // 同步发送
El SendResult devuelto tiene cuatro estados: SEND OK (éxito), FLUSH_DISK_TIMEOUT (tiempo de espera de flash), FLUSH_SLAVE_TIMEOUT (tiempo de espera de sincronización), SLAVE_NOT_AVAILABLE,
1.2 Envío asincrónico
El envío asincrónico se refiere al método de comunicación en el que el remitente envía los datos sin esperar a que el receptor envíe una respuesta y luego envía el siguiente paquete de datos.
El envío asíncrono de MQ requiere que los usuarios implementen la interfaz de devolución de llamada de envío asíncrono (SendCallback). Después de que el remitente del mensaje envía un mensaje, no necesita esperar una respuesta del servidor para regresar y enviar el segundo mensaje. El remitente recibe la respuesta del servidor a través de la interfaz de devolución de llamada y procesa el resultado de la respuesta.
DefaultMQProducer producer = new DefaultMQProducer("my_producer_group");
producer.send(msg, new SendCallback() {
@Override // 成功回调
public void onSuccess(SendResult sendResult) {
System.out.printf("%s%n",sendResult);
}
@Override // 失败回调
public void onException(Throwable throwable) {
throwable.printStackTrace();
}
});
1.3 Transmisión unidireccional
El envío unidireccional (Oneway) se caracteriza por el hecho de que el remitente solo es responsable de enviar el mensaje, sin esperar a que el servidor responda y no se activa ninguna función de devolución de llamada, es decir, solo envía la solicitud sin esperar la respuesta. Lo más eficiente
DefaultMQProducer producer = new DefaultMQProducer("my_producer_group");
producer.sendOneway(msg);
1.4 Transmisión secuencial
En Kafka, los mensajes se pueden enviar secuencialmente a través de una estrategia de partición personalizada. El principio de realización es enviar el mismo tipo de mensajes a la misma partición.
En RocketMQ, se logra un efecto de partición similar a kafka basado en múltiples colas de mensajes . Si la cantidad de datos que un tema debe enviar y recibir es muy grande, se necesita una máquina que admita el procesamiento en paralelo para aumentar la velocidad de procesamiento. En este momento, un tema puede configurar una o más colas de mensajes según las necesidades . Una vez que el tema tiene varias colas de mensajes, los mensajes se pueden enviar a cada cola de mensajes en paralelo y los consumidores también pueden leer y consumir mensajes de varias colas de mensajes en paralelo.
2. Reglas de distribución
2.1 Reglas predeterminadas
Al personalizar la estrategia de envío para darse cuenta de que los mensajes solo se envían a la misma cola, debido a que un tema tendrá múltiples Colas de mensajes, si se usa la configuración predeterminada del Productor, el Productor enviará mensajes a cada Cola de mensajes a su vez. Cuando el consumidor consume mensajes, consumirá la cola de mensajes asignada de acuerdo con la estrategia de equilibrio de carga.
2.2 Personalizado
Sin configuraciones específicas, se desconoce a qué cola de mensajes se envía un determinado mensaje y qué consumidor consume. Si la empresa requiere que enviemos mensajes a la Cola de mensajes especificada, por ejemplo, envíe el mismo tipo de mensajes a la misma Cola de mensajes. ¿Es posible lograr la función de mensajes secuenciales?
Al igual que kafka, rocketMQ también proporciona la función de enrutamiento de mensajes.Podemos personalizar la estrategia de distribución de mensajes e implementar nuestra propia estrategia de distribución de mensajes mediante la implementación de MessageQueueSelector.
DefaultMQProducer producer = new DefaultMQProducer("my_producer_group");
SendResult sendResult = producer.send(msg, new MessageQueueSelector() {
@Override
public MessageQueue select(List<MessageQueue> list, Message message, Object o) {
int key=o.hashCode();
int size = list.size(); // 当前topic的消息队列数
int index = key%size; // 目标队列索引
return list.get(index); // list.get(0);
}
},"key_"+i);