Modo de envío y modo de consumo de RocketMQ

Prefacio

Hola a todos, Xiao A Giao está aquí para conversar sobre la tecnología MQ con todos.

A través del estudio de los artículos anteriores, obtuvimos una comprensión preliminar de la arquitectura básica de RocketMQ, por lo que hoy Xiao A Giao lo acompañará a algunas cosas prácticas y usará el código para echar un vistazo a los diversos modos de envío y modos de consumo de RocketMQ. Bien, comencemos.

Preparación del entorno RocketMQ

Esta vez nuestro entorno está construido en base a Docker, necesitamos preparar una máquina virtual CentOS7 (la instalación de la máquina virtual no se presenta aquí).

Xiao Ah Giao usa el sistema de máquina virtual CentOS7 instalado en VMware. Antes de la instalación formal del entorno, para la conveniencia de la prueba, apagamos el firewall del sistema centos. Luego, debemos instalar docke y docker-compose en esta máquina virtual. Puede consultar https://www.runoob.com/docker/centos-docker-install.html para conocer los pasos de instalación específicos . Algunos comandos de docker de uso común también están disponibles. Es muy conveniente consultarlo en este sitio web, Xiao A Giao lo comparte con todos aquí.

Después de instalar docker y docker-compose, estamos a punto de instalar el entorno RocketMQ. Para conocer los pasos de instalación específicos, consulte la parte docker-compose de implementación con un clic en https://gitee.com/lm970585581/docker-rocketmq .

Los pasos son muy simples, básicamente se puede considerar como una instalación con un solo clic, sin embargo, Xiao A Giao estuvo preocupado por un problema durante mucho tiempo durante el proceso de instalación.

Déjame contarte los problemas encontrados y las soluciones, este es el punto clave.

Xiao Ah Giao siguió los pasos paso a paso, y ocurrió una tragedia cuando start.sh se ejecutó en el último paso.

Si todo es normal, después de ejecutar este paso, se iniciará un total de tres contenedores en la ventana acoplable, a saber, el servidor de nombres, el agente y la consola de control de rocketMQ, pero cuando Xiao A Giao ejecuta la ventana acoplable ps para verificar los contenedores en ejecución, descubre que solo hay Se están ejecutando dos contenedores y el corredor se ha ido.

Así que abre localhost: 8180 ( dirección de la consola de control ) y descubre que la consola está vacía.

Entonces comenzamos a ver el registro de inicio del contenedor del agente, el comando utilizado es: docker logs -f -t --número de línea de cola nombre del contenedor 

El mensaje de error encontrado es java.io.FileNotFoundException: /etc/rocketmq/broker.conf (Permiso denegado)

El monje que llegó al segundo lugar real estaba confundido y confundido.

Después de mucho trabajo, finalmente encontré la razón. Debido a que el módulo de seguridad selinux en centos7 ha desactivado los permisos, el archivo broker.conf no se puede leer. El príncipe que hizo específicamente este módulo de seguridad no lo estudió detenidamente. No se usa en la actualidad, así que use el comando setenforce 0 en linux para apagarlo.

Luego reinicie el contenedor del agente y descubra que el problema está resuelto.

Una vez que se complete la implementación, ingresaremos nuestro contenido principal hoy. ¿Cuáles son los modos de entrega y los modos de consumo de RocketMQ?

 

Envío de RocketMQ

 

Enviar sincrónicamente

Veamos primero un fragmento del código de productor:

import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
import com.alibaba.rocketmq.client.producer.SendResult;
import com.alibaba.rocketmq.common.message.Message;
import com.alibaba.rocketmq.remoting.common.RemotingHelper;

public class RocketMQProducer {
    // RocketMQ的生产者类
    private static DefaultMQProducer producer;
    static {
        // 构建生产者对象,指定生产组
        producer=new DefaultMQProducer("test_group");
        // 设置NameServer的地址,拉取路由信息
        producer.setNamesrvAddr("192.168.220.110:9876");
        try {
            // 启动生产者
            producer.start();
        } catch (MQClientException e) {
            e.printStackTrace();
        }
    }
    public static void send(String topic,String message) throws Exception {
        // 构建消息对象
        Message msg=new Message(topic,
                "",//这里存放的Tag 我们之后会讲解
                message.getBytes(RemotingHelper.DEFAULT_CHARSET));
        SendResult send = producer.send(msg);
        System.out.println(send);
    }

    public static void main(String[] args) {
        try {
            send("test","hello world!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

El fragmento de código anterior es el código para que el productor envíe mensajes a RocketMQ. De hecho, este método es el llamado envío síncrono de mensajes a MQ

Entonces, ¿qué significa enviar mensajes sincrónicamente a MQ?

La llamada sincronización significa que envía un mensaje a MQ a través de esta línea de código, SendResult sendResult = producer.send (msg), y luego se quedará atascado aquí, y el código no puede bajar.

Tienes que esperar a que MQ te devuelva un resultado. Después de obtener el resultado, tu programa continuará ejecutándose.

Este es el llamado modo de transmisión síncrona.

 

Envío asincrónico

Luego miramos el código para el envío asincrónico:

import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
import com.alibaba.rocketmq.client.producer.SendCallback;
import com.alibaba.rocketmq.client.producer.SendResult;
import com.alibaba.rocketmq.common.message.Message;
import com.alibaba.rocketmq.remoting.common.RemotingHelper;

public class RocketMQProducer {
    // RocketMQ的生产者类
    private static DefaultMQProducer producer;
    static {
        // 构建生产者对象,指定生产组
        producer=new DefaultMQProducer("test_group");
        // 设置NameServer的地址,拉取路由信息
        producer.setNamesrvAddr("192.168.220.110:9876");
        try {
            // 启动生产者
            producer.start();
        } catch (MQClientException e) {
            e.printStackTrace();
        }
        // 设置异步发送失败的时候不重试
        producer.setRetryTimesWhenSendAsyncFailed(0);
    }
    public static void send(String topic,String message) throws Exception {
        // 构建消息对象
        Message msg=new Message(topic,
                "",//这里存放的Tag 我们之后会讲解
                message.getBytes(RemotingHelper.DEFAULT_CHARSET));
        producer.send(msg, new SendCallback() {
            public void onSuccess(SendResult sendResult) {
                System.out.println(sendResult);
            }
            public void onException(Throwable throwable) {
                System.out.println(throwable);
            }
        });

    }

    public static void main(String[] args) {
        try {
            send("test","hello world!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Esto significa que después de que se envía el mensaje, el código continúa agotándose, y cuando mq devuelve el resultado, si lo devuelve correctamente, llamará a la función de devolución de llamada al método onSuccess, y si falla, llamará al método onException.

Este es un envío asíncrono, su característica es que no bloquea el programa y se llama a la función callback después de que el mensaje devuelve el resultado.

 

Envío unidireccional

Hay otra forma de envío, llamada envío unidireccional, entonces, ¿qué es el envío unidireccional?

el código se muestra a continuación:

productor.enviarOneway (mensaje);

Significa que el productor envía un mensaje a MQ. Después de enviar, el programa continúa ejecutándose sin bloquearse, y no le importa el valor de retorno de MQ.

En otras palabras, después de enviarlo, no importa.

El método de envío de RocketMQ se presenta aquí. Discutiremos los escenarios de uso específicos en un artículo posterior, siempre que estos métodos estén claros por ahora.

 

Consumo de RocketMQ

Empuje el consumo

Echemos un vistazo al código consumido por push

import com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;
import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import com.alibaba.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.common.message.MessageExt;

import java.io.UnsupportedEncodingException;
import java.util.List;

import static com.alibaba.rocketmq.remoting.common.RemotingHelper.DEFAULT_CHARSET;

public class RocketMQConsumer {
    public static void main(String[] args) throws MQClientException {
        // 创建push消费者实例,指定消费者组
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("test_group");
        // 设置NameServer的地址,拉取路由信息
        consumer.setNamesrvAddr("192.168.220.110:9876");
        // 订阅test Topic , 第二个参数是Tag
        consumer.subscribe("test",null);
        // 注册消费者监听器,接收到消息就会调用这个方法
        consumer.registerMessageListener(new MessageListenerConcurrently() {
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
                // 在这里进行消息的处理
                for (MessageExt t : msgs) {
                    try {
                        System.out.println(new String(t.getBody(), DEFAULT_CHARSET));
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                }
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        // 启动消费者实例
        consumer.start();
        System.out.println("----------Consumer Start-----------");
    }
}

Todos prestan atención al nombre de clase de Consumer: DefaultMQPushConsumer.

Podemos extraer una pieza clave de información del nombre de la clase: Push. De hecho, podemos ver desde aquí que el consumo actual de mensajes que usamos es en realidad el modo Push.

Entonces, ¿qué es el modelo de consumo Push?

En pocas palabras, Broker enviará mensajes activamente a sus consumidores, y sus consumidores recibirán pasivamente mensajes enviados por Broker y luego los procesarán.

Este es el llamado modo Push, lo que significa que Broker envía mensajes activamente a los consumidores.

Tire del consumo

A continuación, hablamos brevemente sobre la forma de consumo de Pull.

El consumo de extracción es en realidad muy fácil de entender, es decir, el Broker ya no envía mensajes de forma activa a los consumidores, sino que los consumidores envían solicitudes para extraer mensajes de Broker.

En cuanto a cuándo usar el modo Push y cuándo usar el modo Pull, hablaremos de este tema más adelante.

 

para resumir

Hoy usamos Docker para implementar rápidamente el entorno RocketMQ y compartimos los problemas y las soluciones encontradas al implementar el entorno para los amigos. Espero que los amigos no puedan comenzar cuando se encuentren con este problema nuevamente.

Después de eso, escribimos el código del productor y el consumidor juntos, y hablamos sobre varios modos de envío y modos de consumo de RocketMQ. Creo que mis amigos deberían ganar algo.

Eso es todo por el intercambio de hoy. Espero que mis amigos continúen apoyándome, para que el próximo intercambio esté allí.

Supongo que te gusta

Origin blog.csdn.net/zx309519477/article/details/108753907
Recomendado
Clasificación