RocketMQ sends synchronous, asynchronous, one-way messages

Explain

The next step is to make simple use of various types of messages, based on examples from the RocketMQ website. After familiarizing yourself with basic usage and the characteristics of various types of messages, take the time to analyze the internal principles.

Base Tool Class

In the next example, the following tool class, RocketMqUtil, is used, whose primary purpose is to encapsulate the Name Server address, Topic, producer, or consumer of RocketMQ. So the code for this tool class is pasted here first:

package com.lzj.rocketmq;

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;

public class RocketMqUtil {

    public static final String NAME_SERVER_ADDR = "192.168.6.130:9876";
    public static final String TOPIC = "topic_simple_message";

    public static DefaultMQProducer getDefaultMQProducer() {
        try {
            DefaultMQProducer defaultMQProducer = new DefaultMQProducer();
            defaultMQProducer.setProducerGroup("TEST_PRODUCER");
            defaultMQProducer.setNamesrvAddr(NAME_SERVER_ADDR);
            //Number of retries after sending a failed message synchronously
            defaultMQProducer.setRetryTimesWhenSendFailed(0);
            //Number of retries after sending a failed message asynchronously
            defaultMQProducer.setRetryTimesWhenSendAsyncFailed(0);
            defaultMQProducer.start();
            return defaultMQProducer;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Initialization RocketMQ An exception occurred at the time of the producer");
        }
    }

    public static DefaultMQPushConsumer getDefaultMQPushConsumer() throws MQClientException {
        try {
            DefaultMQPushConsumer defaultMQPushConsumer = new DefaultMQPushConsumer();
            defaultMQPushConsumer.setConsumerGroup("TEST_CONSUMER");
            defaultMQPushConsumer.setNamesrvAddr(NAME_SERVER_ADDR);
            return defaultMQPushConsumer;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Initialization RocketMQ Exceptions occur when consumers");
        }
    }
}

Test Code

Because the code is simple, it's straightforward, up source:

package com.lzj.rocketmq;

import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.nio.charset.Charset;
import java.util.List;

@SpringBootTest
@Slf4j
public class SimpleMessageTest {

    /**
     * Send Synchronization Message
     * @throws InterruptedException
     * @throws RemotingException
     * @throws MQClientException
     * @throws MQBrokerException
     */
    @Test
    public void sendMessageSynchronously() throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
        DefaultMQProducer defaultMQProducer = RocketMqUtil.getDefaultMQProducer();
        Message message = new Message(RocketMqUtil.TOPIC, "send_message_synchronously", "Synchronization message".getBytes(Charset.forName("UTF-8")));
        SendResult sendResult = defaultMQProducer.send(message);
        log.info("Synchronization message, result name:{}´╝îResult value:{}", sendResult.getSendStatus().name(),
                sendResult.getSendStatus().ordinal());
        defaultMQProducer.shutdown();
    }

    /**
     * Send Asynchronous Message
     * @throws RemotingException
     * @throws MQClientException
     * @throws InterruptedException
     */
    @Test
    public void sendMessageAsynchronously() throws RemotingException, MQClientException, InterruptedException {
        DefaultMQProducer defaultMQProducer = RocketMqUtil.getDefaultMQProducer();
        Message message = new Message(RocketMqUtil.TOPIC, "send_message_asynchronously", "Asynchronous message".getBytes(Charset.forName("UTF-8")));
        defaultMQProducer.send(message, new SendCallback(){

            @Override
            public void onSuccess(SendResult sendResult) {
                log.info("send message success." + sendResult.getSendStatus().ordinal());
            }

            @Override
            public void onException(Throwable throwable) {
                log.info("send message fail.");
            }
        });
        Thread.sleep(5000L);
        defaultMQProducer.shutdown();
    }

    /**
     * One-way transmission, the client sends only, does not wait for a response, there is some security, generally used for logging functions
     * @throws RemotingException
     * @throws MQClientException
     * @throws InterruptedException
     */
    @Test
    public void sendMessageOneway() throws RemotingException, MQClientException, InterruptedException {
        DefaultMQProducer defaultMQProducer = RocketMqUtil.getDefaultMQProducer();
        Message message = new Message(RocketMqUtil.TOPIC, "send_message_oneway", "One-way message".getBytes(Charset.forName("UTF-8")));
        defaultMQProducer.sendOneway(message);
        defaultMQProducer.shutdown();
    }

    @Test
    public void consumeMessage() throws Exception {
        DefaultMQPushConsumer defaultMQPushConsumer = RocketMqUtil.getDefaultMQPushConsumer();
        defaultMQPushConsumer.subscribe(RocketMqUtil.TOPIC, "*");
        defaultMQPushConsumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list,
                                                            ConsumeConcurrentlyContext consumeConcurrentlyContext) {
                log.info("Number of messages consumed:{}", list.size());
                list.stream().map(messageExt -> new String(messageExt.getBody(), Charset.forName("UTF-8")))
                        .map(String::new).forEach(System.out::println);
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        defaultMQPushConsumer.start();
        Thread.sleep(5000L);
    }


}

Examples of sending and consuming three types of basic messages are shown here:

**Synchronization Message: ** After the client sends the message to the Master Broker, it is necessary for the Master Broker to synchronize the message to the corresponding Slave Broker before the Broker will respond to the client. This method responds slowly to clients, but has strong data security and a low risk of data loss.

**Asynchronous Message: ** Once the client sends the message to the Master Broker, the broker responds to the client as long as the Master Broker processes the message, without waiting for the Master Broker to synchronize the message to the corresponding Slave Broker. This method responds quickly to the client, but there is a risk that the message may be lost when the message response client is downloaded after Master Broker processes it.

**One-way Messages: **Clients are responsible for sending messages only and do not wait for Broker to respond. This is the most efficient way, but also at the highest risk of message loss. It is commonly used in scenarios where messages can be tolerated with certain loss.

Effect Display

You can see from the RocketMQ console that the message was actually sent successfully (synchronous messages were sent twice during the test)

Source consumers also consume data successfully:

Tags: Java Distribution

Posted on Thu, 11 Nov 2021 11:39:17 -0500 by dzoddi