RocketMQ-API

2、消費者

各消費者は1つのトピックのみをフォローできます。

メッセージを送信するには、次の条件が必要です。

  • コンシューマーグループの名前を指定します(デフォルトの名前は使用できません。エラーが報告されます)

  • namesrvアドレスの構成(必須)

  • トピック名を指定してください(必須)

  • タグ/キーの指定(オプション)

2.1、クラスタリング

クラスターモード、デフォルト。

たとえば、5つのコンシューマーを開始し、プロデューサーがメッセージを生成した後、ブローカーはメッセージを消費する5つのコンシューマーの1つを選択するため、ポイントツーポイントの消費モデルに属します。

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、放送

ブロードキャストモード。

たとえば、5つのコンシューマーを開始し、プロデューサーがメッセージを生成した後、ブローカーはメッセージを5つのコンシューマーにブロードキャストします。5つのコンシューマーは1回消費し、それぞれが1回消費します。

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

2.3.2つのモードの比較

  • クラスターはデフォルトでデフォルトであり、ブロードキャストモードは手動で構成する必要があります。

  • メッセージ:クラスターモードの複数のコンシューマーは、1つのコンシューマーのみを消費します。ブロードキャストモードの各コンシューマーは、このメッセージを消費します。

  • ブロードキャストモードでは、メッセージを送信した後、現在ブロードキャストされているすべてのコンシューマーによって消費されますが、新しく追加されたコンシューマーはこのメッセージを消費しません。理解しやすいです。村のスピーカーが村全体を叫んで卵を集めました。あなたの村の新しい人、その人は昨日スピーカーによって叫ばれたニュースを聞いたことがなかったに違いありません。

3、TAG && KEY

メッセージを送信/消費するときに、タグ/キーを指定してメッセージをフィルタリングし、ワイルドカードをサポートできます。*これは、フィルタリングせずにこのトピックの下のすべてのメッセージを消費することを意味します。

org.apache.rocketmq.common.message.Messageソースコードを見ると、メッセージを送信するときにタグとキーを指定できることがわかります。

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

といった:

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!");
    }
}

出力結果:

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

コントロールコンソールを確認すると、タグとキーが有効になっていることがわかります。

 

消費するときに、このトピックのすべてのメッセージである*を指定すると、次のようなプレフィックスワイルドカードを指定できます。

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

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

また、あまり一般的ではないSQL式フィルタリングもサポートしています。BBはもうありません。

4.よくある間違い

4.1、sendDefaultImpl呼び出しタイムアウト

4.1.1、異常

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、解決する

1.クラウドサーバーの場合は、最初にセキュリティグループがポート9876へのアクセスを許可しているかどうか、ファイアウォールがオンになっているかどうか、オンになっている場合は9876がマップアウトされているかどうかを確認します。

2.構成ファイルを変更しbroker.conf、以下を追加します。

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

namesrvとbrokerを起動するときにローカルIPを追加します(Alibaba Cloudサーバーを使用しています。これがパブリックIPです)。

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

4.2、このトピックのルート情報はありません

4.2.1、異常

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。解決する

明らかに送信は成功しました。今はタイムアウトではありませんが、そのようなトピックはないことがわかります。毎回手動で作成することはできないため、ブローカーを起動するときにパラメーターを指定して、ブローカーが自動的に作成できるようにすることができます。次のように

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

 

終わり

おすすめ

転載: blog.csdn.net/My_SweetXue/article/details/107381324