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
終わり