RocketMQ - API

2、Consumer

Each consumer can only follow one topic.

The following conditions must be necessary to send a message:

  • Specify the name of the consumer group (the default one cannot be used, an error will be reported)

  • Configure namesrv address (required)

  • Specify topic name (required)

  • Specify tag/key (optional)

2.1、CLUSTERING

Cluster mode, the default.

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

public class Consumer {
    public static void main(String[] args) throws Exception {
        // 指定消费组名为my-consumer
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("my-consumer");
        // 配置namesrv地址
        consumer.setNamesrvAddr("124.57.180.156:9876");
        // 订阅topic:myTopic001 下的全部消息(因为是*,*指定的是tag标签,代表全部消息,不进行任何过滤)
        consumer.subscribe("myTopic001", "*");
        // 注册监听器,进行消息消息。
        consumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
                for (MessageExt msg : msgs) {
                    String str = new String(msg.getBody());
                    // 输出消息内容
                    System.out.println(str);
                }
                // 默认情况下,这条消息只会被一个consumer消费,这叫点对点消费模式。也就是集群模式。
                // ack确认
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        // 启动消费者
        consumer.start();
        System.out.println("Consumer start");
    }
}

2.2、BROADCASTING

Broadcast mode.

For example, after starting five Consumers and the Producer produces a message, the Broker will broadcast the message to the five Consumers. The five Consumers consume once and each consumes once.

// 代码里只需要添加如下这句话即可:
consumer.setMessageModel(MessageModel.BROADCASTING); 

2.3. Comparison of the two modes

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

  • A message: Multiple Consumers in the cluster mode will only have one Consumer to consume. Each Consumer in the broadcast mode will consume this message.

  • In the broadcast mode, after sending a message, it will be consumed by all Consumers currently being broadcasted, but the newly added Consumers will not consume this message. It is easy to understand: the village loudspeaker shouted the whole village to collect eggs, second A new person in your village, that person must have not heard the news shouted by the loudspeaker yesterday.

3、TAG&&KEY

When sending/consuming messages, you can specify tag/key to filter messages and support wildcards. *It means to consume all the messages under this topic without filtering.

Looking at the org.apache.rocketmq.common.message.Messagesource code, you can find that you can specify tags and keys when sending messages:

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

such as:

public class ProducerTagsKeys {
    public static void main(String[] args) throws Exception {
        // 指定生产组名为my-producer
        DefaultMQProducer producer = new DefaultMQProducer("my-producer");
        // 配置namesrv地址
        producer.setNamesrvAddr("124.57.180.156:9876");
        // 启动Producer
        producer.start();
        // 创建消息对象,topic为:myTopic001,消息内容为:hello world,且tags为:test-tags,keys为test-keys
        Message msg = new Message("myTopic001", "test-tags", "test-keys", "hello world".getBytes());
        // 发送消息到mq,同步的
        SendResult result = producer.send(msg);
        System.out.println("发送消息成功!result is : " + result);
        // 关闭Producer
        producer.shutdown();
        System.out.println("生产者 shutdown!");
    }
}

Output result:

发送消息成功!result is : SendResult [sendStatus=SEND_OK, msgId=A9FE854149DC18B4AAC26FA4B7200000, offsetMsgId=7B39B49D00002A9F0000000000058DA6, messageQueue=MessageQueue [topic=myTopic001, brokerName=broker-a, queueId=3], queueOffset=3]
生产者 shutdown!

Check the control console, you can find that tags and keys have taken effect:

 

When consuming, if you specify *, that is all the messages under this topic, we can specify a prefix wildcard, such as:

// 这样就只会消费myTopic001下的tag为test-*开头的消息。
consumer.subscribe("myTopic001", "test-*");

// 代表订阅Topic为myTopic001下的tag为TagA或TagB的所有消息
consumer.subscribe("myTopic001", "TagA||TagB");

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

4. Common mistakes

4.1、sendDefaultImpl call timeout

4.1.1, abnormal

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, solve

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

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

brokerIP1=我用的是阿里云服务器,这里是我的公网IP

Add the local IP when starting namesrv and broker (I use Alibaba Cloud 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, abnormal

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. Resolve

Obviously the sending was successful, it is no longer the timeout just now, but it tells us that there is no such topic. That can't be created manually every time, so when you start the broker, you can specify the parameters to let the broker automatically create it for us. as follows

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

 

END

Guess you like

Origin blog.csdn.net/My_SweetXue/article/details/107381324