RocketMQ entry to the ground novice can also understand the principle and practice!

Keywords: Java Apache github Netty

Learning any technology is a two-step process:

  1. Setting up the environment

  2. helloworld

I'm no exception. I'll do it directly.

1, RocketMQ installation

1. Documents

Official website

http://rocketmq.apache.org

GitHub

https://github.com/apache/rocketmq

2. Download

wget https://mirror.bit.edu.cn/apache/rocketmq/4.7.0/rocketmq-all-4.7.0-bin-release.zip

We are based on Centos8 and are learning from official documents, so the download address is also official.

Go to the official website to find the right version to download. At present, my latest version here is version 4.7.0.

http://rocketmq.apache.org/dowloading/releases/

 

https://www.apache.org/dyn/closer.cgi?path=rocketmq/4.7.0/rocketmq-all-4.7.0-bin-release.zip

 

3. Preparations

3.1 decompression

unzip rocketmq-all-4.7.0-bin-release.zip

3.2. Install jdk

sudo yum install java-1.8.0-openjdk-devel

4. Start

4.1. Start namesrv

cd rocketmq-all-4.7.0-bin-release/bin
./mqnamesrv

4.2 start broker

cd rocketmq-all-4.7.0-bin-release/bin
./mqbroker -n localhost:9876

Common errors and solutions:

Common error: failed to start broker Cannot allocate memory

[root@node-113b bin]# ./mqbroker -n localhost:9876
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000005c0000000, 8589934592, 0) failed
; error='Cannot allocate memory' (errno=12)#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 8589934592 bytes for committing reserved memory.
# An error report file with more information is saved as:
# /usr/local/rocketmq/bin/hs_err_pid1997.log

Solution:

Because the default memory allocation is too large, it exceeds the local memory and directly OOM.

Modify the following two scripts in bin / directory

runbroker.sh
runserver.sh

Search for - server -Xms in both scripts, allocate its memory a little bit, 512MB will be enough if you play by yourself, enough!

4.3. Startup success identification

namesrv start success id:

broker start success id:

2, Installation of RocketMQ console

At present, there are two ways to obtain the console:

  1. Third party websites to download off the shelf, such as csdn.

  2. The official source code package is compiled by itself. There is no official one.

Of course, we take an official approach here.

1. Official documents

github warehouse

https://github.com/apache/rocketmq-externals

Chinese guide

https://github.com/apache/rocketmq-externals/blob/master/rocketmq-console/doc/1_0_0/UserGuide_CN.md

2. Download source code

https://codeload.github.com/apache/rocketmq-externals/zip/master

3. Modify configuration (optional)

After downloading and decompressing, the file directory is as follows:

Modify rocketmq consolesrcmain resourcesapplication.properties Documented server.port That's it. The default is 8080.

4. Compile package

Enter rocketmq console, and compile and package with maven

mvn clean package -DskipTests

After packaging, we will generate our spring boot jar program under target, and directly start Java jar.

5. Launch console

Throw the compiled and packaged springboot program onto the server, and execute the following command to start it

java -jar rocketmq-console-ng-1.0.1.jar --rocketmq.config.namesrvAddr=127.0.0.1:9876

If you want to start in the background, nohup&

Visit to see the effect:

3, Testing

rocketmq provides us with testing tools and classes, which can be easily tested after installation.

0. Preparation

The default testing tool provided by rocketmq is in bin directory, which is called tools.sh . Before testing, we need to configure this script and specify the namesrv address for it. Otherwise, when testing sending / consuming messages, the following error will appear: connect to null failed:

22:49:02.470 [main] DEBUG i.n.u.i.l.InternalLoggerFactory - Using SLF4J as the default logging framework
RocketMQLog:WARN No appenders could be found for logger (io.netty.util.internal.PlatformDependent0).
RocketMQLog:WARN Please initialize the logger system properly.
java.lang.IllegalStateException: org.apache.rocketmq.remoting.exception.RemotingConnectException: connect to null failed

The configuration is as follows:

vim tools.sh
#In export Java_ Add the following code to home
export NAMESRV_ADDR=localhost:9876

1. Send message

./tools.sh org.apache.rocketmq.example.quickstart.Producer

If it succeeds, you will see the log of the crash, because this class will send 1000 messages to the Topic of TopicTest.

2. Consumer News

./tools.sh org.apache.rocketmq.example.quickstart.Consumer

If it is successful, you will see the log of the crash, because this class will consume all the messages under the TopicTest. The 1000 just sent will be consumed.

3. Console

After sending successfully, we can naturally come to the control console to see the information, consumption and so on

4, Architecture and roles

1. Architecture diagram

2. Role

2.1,Broker

  • Understood as RocketMQ itself

  • broker is mainly used for producer and consumer to receive and send messages

  • broker will regularly submit its own information to nameserver

  • It is the message storage and forwarding server of message middleware

  • When each Broker node starts, it will traverse the NameServer list, establish a long connection with each NameServer, register its own information, and then report regularly

2.2,Nameserver

  • It's understood as the effect of zookeeper, but instead of using zk, he wrote a nameserver to replace zk

  • The bottom layer is implemented by netty, which provides the functions of route management, service registration and service discovery. It is a stateless node

  • Nameserver is a service discoverer. All roles in the cluster (producer, broker, consumer, etc.) need to report their status to nameserver regularly, so that they can discover each other. If they don't report after the timeout, nameserver will remove them from the list

  • nameserver can deploy multiple. When multiple nameservers exist, other roles report information to them at the same time to ensure high availability,

  • NameServer clusters do not communicate with each other, and there is no concept of active and standby

  • Nameserver is stored in memory. Information such as broker and topic in nameserver will not be persisted by default, so it is a stateless node

2.3,Producer

  • Producer of message

  • Randomly select one of the NameServer nodes to establish a long connection to obtain topic routing information (including the queues under topic, which broker s these queues are distributed on, etc.)

  • Next, establish a long connection to the master providing the topic service (because rocketmq can only write messages to the master), and send the heartbeat to the master regularly

2.4,Consumer

  • Consumers of messages

  • Get the routing information of the Topic through the NameServer cluster, and connect to the corresponding Broker to consume messages

  • Since both Master and Slave can read messages, the Consumer will establish a connection with both Master and Slave to consume messages

3. Core process

  • All brokers are registered on Nameserver

  • When Producer sends a message, it will get the topic information of the message from the Nameserver

  • Producer establishes a long connection to all masters providing services, and sends heartbeat to the master regularly

  • Consumer obtains the routing information of Topic through NameServer cluster

  • The Consumer will establish a connection with all masters and all slaves to listen for new messages

5, Core concepts

1,Message

Message carrier. Topic must be specified when message is sent or consumed. Message has an optional Tag entry for filtering messages, and additional key value pairs can be added.

2,topic

The logical classification of messages. Before sending a message, you must specify a topic to send it. That is, send the message to this topic. This topic is specified for consumption when consuming messages. It's logical classification.

3,queue

One topic will be divided into N queues, and the number is configurable. Message itself is actually stored on the queue, and what consumers consume is also the message on the queue. Say more, for example, if a topic has four queues and five consumers are consuming the topic, then one consumer will be wasted. Because of the load balancing strategy, each consumer consumes one queue, 5 > 4, and overflows one. This will not work.

4,Tag

Tag is a further subdivision of Topic. As the name implies, tag. Each message can be tagged when it is sent. When it is consumed, it can be filtered according to the tag and consumed selectively.

5,Message Model

Message model: Clustering and Broadcasting

6,Message Order

Message order: order and concurrency

7,Producer Group

Message producers group

8,Consumer Group

Message consumer group

6, ACK

First of all, make it clear that the ACK mechanism is on the Consumer side, not the Producer side. That is to say, the Consumer needs to confirm the ACK after consuming the message. If the message is not confirmed, it means that the consumption fails. At this time, the Broker will try again (only in cluster mode). The meaning of ACK is: the Consumer said: ok, I succeeded in consumption. Mark this message as consumed.

7, Consumption mode

1. Clustering mode

1.1 diagram

 

1.2 characteristics

  • Each message only needs to be processed once, and the broker will only send the message to one consumer in the consumption cluster

  • Routing to the same machine cannot be guaranteed during message replay

  • Consumption status maintained by broker

2. Broadcasting mode

2.1 diagram

 

2.2 characteristics

  • Consumption progress is maintained by consumer

  • Ensure that every consumer consumes a message

  • The message of consumption failure will not be re invested

8, Java API

explain:

  • RocketMQ server version is the latest version: 4.7.0

  • The latest version of Java client: 4.7.0

pom is as follows

<dependency>
    <groupId>org.apache.rocketmq</groupId>
    <artifactId>rocketmq-client</artifactId>
    <version>4.7.0</version>
</dependency>

1,Producer

The following conditions are necessary for sending messages:

  • Specify production group name (cannot use default, error will be reported)

  • Configure namesrv address (required)

  • Specify topic name (required)

  • Specify tag/key (optional)

Verify whether the message is sent successfully: after sending the message, you can start the consumer to consume, or you can go to the control console to see whether the message exists.

1.1 send (synchronous)

public class Producer {
    public static void main(String[] args) throws Exception {
        //Specify the production group name as my producer
        DefaultMQProducer producer = new DefaultMQProducer("my-producer");
        //Configure namesrv address
        producer.setNamesrvAddr("124.57.180.156:9876");
        //Start Producer
        producer.start();
        //Create a message object with topic of myTopic001 and message content of hello world
        Message msg = new Message("myTopic001", "hello world".getBytes());
        //Send message to mq, synchronous
        SendResult result = producer.send(msg);
        System.out.println("Message sent successfully! result is : " + result);
        //Close Producer
        producer.shutdown();
        System.out.println("producer shutdown!");
    }
}

Output results:

Message sent successfully! result is : SendResult [sendStatus=SEND_OK, msgId=A9FE854140F418B4AAC26F7973910000, offsetMsgId=7B39B49D00002A9F00000000000589BE, messageQueue=MessageQueue [topic=myTopic001, brokerName=broker-a, queueId=0], queueOffset=7]
Producer shutdown!

1.2 send (batch)

public class ProducerMultiMsg {
    public static void main(String[] args) throws Exception {
        //Specify the production group name as my producer
        DefaultMQProducer producer = new DefaultMQProducer("my-producer");
        //Configure namesrv address
        producer.setNamesrvAddr("124.57.180.156:9876");
        //Start Producer
        producer.start();

        String topic = "myTopic001";
        //Create a message object. The topic is myTopic001 and the message content is hello world1/2/3
        Message msg1 = new Message(topic, "hello world1".getBytes());
        Message msg2 = new Message(topic, "hello world2".getBytes());
        Message msg3 = new Message(topic, "hello world3".getBytes());
        //Create a collection of message objects for bulk sending
        List<Message> msgs = new ArrayList<>();
        msgs.add(msg1);
        msgs.add(msg2);
        msgs.add(msg3);
        //The api of batch sending is also send(), but its overload method supports list < message >, which is also synchronous sending.
        SendResult result = producer.send(msgs);
        System.out.println("Message sent successfully! result is : " + result);
        //Close Producer
        producer.shutdown();
        System.out.println("producer shutdown!");
    }
}

Output results:

Message sent successfully! result is : SendResult [sendStatus=SEND_OK, msgId=A9FE854139C418B4AAC26F7D13770000,A9FE854139C418B4AAC26F7D13770001,A9FE854139C418B4AAC26F7D13770002, offsetMsgId=7B39B49D00002A9F0000000000058A62,7B39B49D00002A9F0000000000058B07,7B39B49D00002A9F0000000000058BAC, messageQueue=MessageQueue [topic=myTopic001, brokerName=broker-a, queueId=0], queueOffset=8]
Producer shutdown!

It can be seen from the result that there is only one msgId, so it can be found that although there are three message objects, they are only sent once, which greatly saves the cost of client and server.

Error condition:

The topic for batch sending must be the same. If the message object specifies different topics, an error will be reported during batch sending:

Exception in thread "main" org.apache.rocketmq.client.exception.MQClientException: Failed to initiate the MessageBatch
For more information, please visit the url, http://rocketmq.apache.org/docs/faq/
    at org.apache.rocketmq.client.producer.DefaultMQProducer.batch(DefaultMQProducer.java:950)
    at org.apache.rocketmq.client.producer.DefaultMQProducer.send(DefaultMQProducer.java:898)
    at com.chentongwei.mq.rocketmq.ProducerMultiMsg.main(ProducerMultiMsg.java:29)
Caused by: java.lang.UnsupportedOperationException: The topic of the messages in one batch should be the same
    at org.apache.rocketmq.common.message.MessageBatch.generateFromList(MessageBatch.java:58)
    at org.apache.rocketmq.client.producer.DefaultMQProducer.batch(DefaultMQProducer.java:942)
    ... 2 more

1.3 sendCallBack (asynchronous)

public class ProducerASync {
    public static void main(String[] args) throws Exception {
       //Specify the production group name as my producer
        DefaultMQProducer producer = new DefaultMQProducer("my-producer");
        //Configure namesrv address
        producer.setNamesrvAddr("124.57.180.156:9876");
        //Start Producer
        producer.start();

        //Create a message object with the topic of myTopic001 and the message content of hello world async
        Message msg = new Message("myTopic001", "hello world async".getBytes());
        //Send asynchronously and get the result of sending through SendCallback interface
        producer.send(msg, new SendCallback() {
            //Send successful callback interface
            @Override
            public void onSuccess(SendResult sendResult) {
                System.out.println("Message sent successfully! result is : " + sendResult);
            }
            //Send failed callback interface
            @Override
            public void onException(Throwable throwable) {
                throwable.printStackTrace();
                System.out.println("Failed to send message! result is : " + throwable.getMessage());
            }
        });

        producer.shutdown();
        System.out.println("producer shutdown!");
    }
}

Output results:

Producer shutdown!
java.lang.IllegalStateException: org.apache.rocketmq.remoting.exception.RemotingConnectException: connect to [124.57.180.156:9876] failed
    at org.apache.rocketmq.client.impl.factory.MQClientInstance.updateTopicRouteInfoFromNameServer(MQClientInstance.java:681)
    at org.apache.rocketmq.client.impl.factory.MQClientInstance.updateTopicRouteInfoFromNameServer(MQClientInstance.java:511)
    at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.tryToFindTopicPublishInfo(DefaultMQProducerImpl.java:692)
    at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:556)
    at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.access$300(DefaultMQProducerImpl.java:97)
    at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl$4.run(DefaultMQProducerImpl.java:510)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.rocketmq.remoting.exception.RemotingConnectException: connect to [124.57.180.156:9876] failed
    at org.apache.rocketmq.remoting.netty.NettyRemotingClient.getAndCreateNameserverChannel(NettyRemotingClient.java:441)
    at org.apache.rocketmq.remoting.netty.NettyRemotingClient.getAndCreateChannel(NettyRemotingClient.java:396)
    at org.apache.rocketmq.remoting.netty.NettyRemotingClient.invokeSync(NettyRemotingClient.java:365)
    at org.apache.rocketmq.client.impl.MQClientAPIImpl.getTopicRouteInfoFromNameServer(MQClientAPIImpl.java:1371)
    at org.apache.rocketmq.client.impl.MQClientAPIImpl.getTopicRouteInfoFromNameServer(MQClientAPIImpl.java:1361)
    at org.apache.rocketmq.client.impl.factory.MQClientInstance.updateTopicRouteInfoFromNameServer(MQClientInstance.java:624)
    ... 10 more
Failed to send message! result is : org.apache.rocketmq.remoting.exception.RemotingConnectException: connect to [124.57.180.156:9876] failed

Why is the report wrong? It's very simple. It's asynchronous. It can be seen from the results. Since it's asynchronous, I haven't sent it to mq yet. You should shut it down first. Definitely not, so we'll sleep for 1s before shutdown to see the effect

public class ProducerASync {
    public static void main(String[] args) throws Exception {
       //Specify the production group name as my producer
        DefaultMQProducer producer = new DefaultMQProducer("my-producer");
        //Configure namesrv address
        producer.setNamesrvAddr("124.57.180.156:9876");
        //Start Producer
        producer.start();

        //Create a message object with the topic of myTopic001 and the message content of hello world async
        Message msg = new Message("myTopic001", "hello world async".getBytes());
        //Send asynchronously and get the result of sending through SendCallback interface
        producer.send(msg, new SendCallback() {
            //Send successful callback interface
            @Override
            public void onSuccess(SendResult sendResult) {
                System.out.println("Message sent successfully! result is : " + sendResult);
            }
            //Send failed callback interface
            @Override
            public void onException(Throwable throwable) {
                throwable.printStackTrace();
                System.out.println("Failed to send message! result is : " + throwable.getMessage());
            }
        });

        Thread.sleep(1000);

        producer.shutdown();
        System.out.println("producer shutdown!");
    }
}

Output results:

Message sent successfully! result is : SendResult [sendStatus=SEND_OK, msgId=A9FE854106E418B4AAC26F8719B20000, offsetMsgId=7B39B49D00002A9F0000000000058CFC, messageQueue=MessageQueue [topic=myTopic001, brokerName=broker-a, queueId=1], queueOffset=2]
Producer shutdown!

1.4,sendOneway

public class ProducerOneWay {
    public static void main(String[] args) throws Exception {
        //Specify the production group name as my producer
        DefaultMQProducer producer = new DefaultMQProducer("my-producer");
        //Configure namesrv address
        producer.setNamesrvAddr("124.57.180.156:9876");
        //Start Producer
        producer.start();

        //Create a message object with topic of myTopic001 and message content of hello world oneway
        Message msg = new Message("myTopic001", "hello world oneway".getBytes());
        //It's the most efficient because oneway doesn't care whether it's successful or not. I don't care if it's delivered. So the return is void
        producer.sendOneway(msg);
        System.out.println("Message delivered successfully! , note that this is a successful delivery, not a successful message! Because of me sendOneway I don't know if it's successful or not. I didn't return the value.");
        producer.shutdown();
        System.out.println("producer shutdown!");
    }
}

Output results:

Message delivered successfully! , note that this is a successful delivery, not a successful message! Because I sendOneway didn't know whether it was successful or not. I didn't return the value.
Producer shutdown!

1.5 efficiency comparison

Sendoneway > sendcallback > send batch > send single

It's easy to understand that sendOneway doesn't ask for results, and I'll be responsible for delivery. Whether you fail or succeed, I'm equivalent to a transfer station. When you come, I'll throw it out, and I won't do anything else. So the fastest.

And sendCallBack is that asynchronous sending is certainly more efficient than synchronous sending.

The efficiency of send batch and send single can also be divided into different situations. If there is only one msg to be sent, then gross batch will be carried out and send single will be completed directly.

2,Consumer

Each consumer can only focus on one topic.

The following conditions are necessary for sending messages:

  • Specify consumption group name (cannot use default, error will be reported)

  • Configure namesrv address (required)

  • Specify topic name (required)

  • Specify tag/key (optional)

2.1,CLUSTERING

Cluster mode, default.

For example, after starting five consumers and Producer produces a message, Broker will choose one of the five consumers to consume the message, so it belongs to the point-to-point consumption mode.

public class Consumer {
    public static void main(String[] args) throws Exception {
        //Specify the name of the consumption group as my consumer
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("my-consumer");
        //Configure namesrv address
        consumer.setNamesrvAddr("124.57.180.156:9876");
        //Subscribe to topic: all messages under myTopic001 (because it is *, * specifies the tag tag, which represents all messages without any filtering)
        consumer.subscribe("myTopic001", "*");
        //Register the listener for message messages.
        consumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
                for (MessageExt msg : msgs) {
                    String str = new String(msg.getBody());
                    //Output message content
                    System.out.println(str);
                }
                //By default, this message will only be consumed by one consumer, which is called point-to-point consumption mode. That is cluster mode.
                //ack confirmation
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        //Launch consumer
        consumer.start();
        System.out.println("Consumer start");
    }
}

2.2,BROADCASTING

Broadcast mode.

For example, when five consumers are started and a Producer produces a message, the Broker will broadcast the message to five consumers. Each of the five consumers will consume the message once.

//Just add the following sentence to the code:
consumer.setMessageModel(MessageModel.BROADCASTING); 

2.3 comparison of two modes

  • By default, the cluster is the default, and the broadcast mode needs to be configured manually.

  • One message: multiple consumers in cluster mode only have one Consumer consumption. Every Consumer in broadcast mode consumes this message.

  • In the broadcast mode, after sending a message, it will be consumed by all the consumers currently being broadcast, but the newly added consumers will not consume the message. It's easy to understand that: the village's loudspeakers shout the whole village to get the eggs, and the next day your village's new comer will not hear the news of yesterday's loudspeakers.

3,TAG&&KEY

When sending / consuming messages, you can specify tag/key to filter messages. Wildcards are supported. *Represents the consumption of all messages under this topic without filtering.

look down org.apache.rocketmq.common.message.Message The source code can find that when sending messages, you can specify tag s and keys:

public Message(String topic, String tags, String keys, byte[] body) {
    this(topic, tags, keys, 0, body, true);
}

For example:

public class ProducerTagsKeys {
    public static void main(String[] args) throws Exception {
        //Specify the production group name as my producer
        DefaultMQProducer producer = new DefaultMQProducer("my-producer");
        //Configure namesrv address
        producer.setNamesrvAddr("124.57.180.156:9876");
        //Start Producer
        producer.start();
        //Create a message object with topic of myTopic001, message content of hello world, tags of test tags and keys of test keys
        Message msg = new Message("myTopic001", "test-tags", "test-keys", "hello world".getBytes());
        //Send message to mq, synchronous
        SendResult result = producer.send(msg);
        System.out.println("Message sent successfully! result is : " + result);
        //Close Producer
        producer.shutdown();
        System.out.println("producer shutdown!");
    }
}

Output results:

Message sent successfully! result is : SendResult [sendStatus=SEND_OK, msgId=A9FE854149DC18B4AAC26FA4B7200000, offsetMsgId=7B39B49D00002A9F0000000000058DA6, messageQueue=MessageQueue [topic=myTopic001, brokerName=broker-a, queueId=3], queueOffset=3]
Producer shutdown!

By viewing the control console, you can see that the tags and keys have taken effect:

 

If * is specified during consumption, it is all the messages under this topic. We can specify prefix wildcards, such as:

//In this way, only messages with the tag beginning with test - * under myTopic001 will be consumed.
consumer.subscribe("myTopic001", "test-*");

//Represents all messages with tag a or TagB under subscription Topic myTopic001
consumer.subscribe("myTopic001", "TagA||TagB");

It also supports SQL expression filtering, which is not very common. No BB.

4. Common errors

4.1,sendDefaultImpl call timeout

4.1.1 abnormality

Exception in thread "main" org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException: sendDefaultImpl call timeout
    at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:666)
    at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1342)
    at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1288)
    at org.apache.rocketmq.client.producer.DefaultMQProducer.send(DefaultMQProducer.java:324)
    at com.chentongwei.mq.rocketmq.Producer.main(Producer.java:18)

4.1.2 solution

1. If you are a cloud server, first check whether the security group allows 9876 port access, whether the firewall is enabled, and whether 9876 is mapped out if it is enabled.

2. Modify the configuration file broker.conf , plus:

brokerIP1 = I use alicloud server, here is my public IP

When starting namesrv and broker, add the local IP (I use alicloud server, here is my public IP):

./bin/mqnamesrv -n IP:9876
./bin/mqbroker -n IP:9876 -c conf/broker.conf

4.2,No route info of this topic

4.2.1 abnormality

Exception in thread "main" org.apache.rocketmq.client.exception.MQClientException: No route info of this topic: myTopic001
See http://rocketmq.apache.org/docs/faq/ for further details.
    at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:684)
    at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1342)
    at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1288)
    at org.apache.rocketmq.client.producer.DefaultMQProducer.send(DefaultMQProducer.java:324)
    at com.chentongwei.mq.rocketmq.Producer.main(Producer.java:18)

4.2.2 solution

It's obvious that the transmission is successful. It's no longer the timeout just now, but it tells us that we don't have this topic. It can't be created manually every time, so when starting broker, you can specify parameters to let broker create automatically for us. as follows

./bin/mqbroker -n IP:9876 -c conf/broker.conf autoCreateTopicEnable=true

Posted by muretto on Sat, 27 Jun 2020 20:44:03 -0700