RocketMQ系列之入門

前言

之前我們把RMQ的多Master集羣搭建起來了,我們今天就來看看如何向這個集羣生產消息以及消費消息。

 

集羣搭建回顧

回顧上節的內容,我總結下以下幾步:

第一:最新版RMQ4.2.0要求最低JDK8版本

第二:修改虛擬機的host,配置nameserver域名

第三:安裝RMQ

第四:新建RMQ的消息存儲文件

第五:修改RMQ的日誌輸出

第六:配置Broker配置文件

第七:根據虛擬機實際情況修改runserver.sh和runbroker.sh啓動參數

第八:啓動nameserver再啓動broker

第九:生成控制檯

OK,我們再來看下集羣結果:

 

 

JAVA操作RMQ

第一步:POM引入相關jar

根據GitHub上的quickstart,我直接將我們將來需要用到的jar都導入進來了(你其實只需要導入):

<parent>
   <groupId>org.apache.rocketmq</groupId>
   <artifactId>rocketmq-all</artifactId>
   <version>4.2.0</version>
 </parent>

<dependency>
     <groupId>${project.groupId}</groupId>
     <artifactId>rocketmq-client</artifactId>
   </dependency>
   <dependency>
     <groupId>${project.groupId}</groupId>
     <artifactId>rocketmq-srvutil</artifactId>
   </dependency>
   <dependency>
     <groupId>ch.qos.logback</groupId>
     <artifactId>logback-classic</artifactId>
   </dependency>
   <dependency>
     <groupId>org.javassist</groupId>
     <artifactId>javassist</artifactId>
   </dependency>
   <dependency>
     <groupId>io.openmessaging</groupId>
     <artifactId>openmessaging-api</artifactId>
   </dependency>
   <dependency>
     <groupId>org.apache.rocketmq</groupId>
     <artifactId>rocketmq-openmessaging</artifactId>
     <version>4.2.0</version>

 

第二步:生產者Producer

public class Producer {
   public static void main(String[] args) throws MQClientException, InterruptedException {
       // 聲明一個生產者,需要一個自定義生產者組(後面我們會介紹這個組的概念和作用)
       DefaultMQProducer producer = new DefaultMQProducer("myTestGroup");
       // 設置集羣的NameServer地址,多個地址之間以分號分隔
       producer.setNamesrvAddr("139.196.184.3:9876;139.196.51.36:9876");
       // 啓動生產者實例
       producer.start();
       // 模擬發送100條消息 到Topic爲TopicTest,tag爲tagA,消息內容爲Hello RocketMQ +i
       for (int i = 0; i < 100; i++) {
           try {
               Message msg = new Message("TopicTest" ,"TagA",("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET)
               );
               // 調用Produce的send方法發送消息
               SendResult sendResult = producer.send(msg);
               System.out.printf("%s%n", sendResult);
           } catch (Exception e) {
               e.printStackTrace();
               Thread.sleep(1000);
           }
       }
       // 發送完消息之後調用producer的shutdown()方法關閉producer
       producer.shutdown();
   }
}

 

第三步:消費者Consumer

public class Consumer {
   public static void main(String[] args) throws Exception {
       // 聲明一個消費者consumer,需要傳入一個組
       DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumerTest");
       // 設置集羣的NameServer地址,多個地址之間以分號分隔
       consumer.setNamesrvAddr("139.196.184.3:9876;139.196.51.36:9876");
       // 設置consumer的消費策略
       // CONSUME_FROM_LAST_OFFSET 默認策略,從該隊列最尾開始消費,即跳過歷史消息
       // CONSUME_FROM_FIRST_OFFSET 從隊列最開始開始消費,即歷史消息(還儲存在broker的)全部消費一遍
       // CONSUME_FROM_TIMESTAMP 從某個時間點開始消費,和setConsumeTimestamp()配合使用,默認是半個小時以前
       consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
       // 設置consumer所訂閱的Topic和Tag,*代表全部的Tag
       consumer.subscribe("TopicTest", "*");
       // Listener,主要進行消息的邏輯處理,監聽topic,如果有消息就會立即去消費
       consumer.registerMessageListener(new MessageListenerConcurrently() {
           @Override
           public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
               System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msgs);
               // 返回消費狀態 有2種狀態 CONSUME_SUCCESS 消費成功 RECONSUME_LATER 消費失敗,需要稍後重新消費
               return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
           }
       });
       // 調用start()方法啓動consumer
       consumer.start();
       System.out.printf("Consumer Started.%n");
   }
}

 

OK,現在我們啓動消費者,注意一定是要先啓動消費者,後啓動生產者,這點很好理解,消費者得先訂閱,生產者再生產消息,訂閱之後就能消費消息,當然如果你非要先啓動生產者也行,但是這會有一些問題,會導致有可能消息被重複消費(這點後面我會詳細講解),主要原因是RMQ是通過消費返回消息的狀態來判斷一條消息是否被消費,如果你先啓動生產者,就會造成可能第一個consumer1拿到消息A,還沒返回狀態時,consumer2也拿到了消息A,就會造成重複消費,所以,儘量避免有消息堆積造成消息重複消費,這些我們後面會詳細講,今天主要講入門,如何玩成一個生產消費的過程。下面我們來看看這個demo的結果:

 

producer端(細心的小夥伴會發現生產者怎麼是4個一組4個一組的發的,這裏先賣個關子):

 

consumer端:consumer端是一直啓動的,監聽這它所訂閱的主題,一旦有消息就會去處理

 

我們再來看看控制檯:我是生產了2次100,就就是200條消息,也看到這200條102條落到broker-a上98條落到broker-b上,從這裏也證實了生產者是4個消息一組發送的,所以纔會出現102+98的結果:

這裏就是我們的消費者訂閱的主題:可以點詳情進去看的,這個控制檯其實還是不錯的

 

結束

OK,RMQ的入門就介紹到這裏了,上面賣的關子我還是忍不住想告訴你,其實這個是我們在配置broker時可以指定的,這裏我把Broker配置文件詳細的貼一份給小夥伴們吧,小夥伴們做下相應的修改就能使用了:

brokerClusterName=rocketmq-cluster-justin

brokerName=broker-a

brokerId=0

namesrvAddr=rocketmq-nameserver1:9876;rocketmq-nameserver2:9876

#在發送消息時,自動創建服務器不存在的topic,默認創建的隊列數

defaultTopicQueueNums=4

#是否允許 roker 自動創建Topic,建議線下開啓,線上關閉
autoCreateTopicEnable=true

#是否允許 Broker 自動創建訂閱組,建議線下開啓,線上關閉
autoCreateSubscriptionGroup=true

#Broker對外服務的監聽端口
listenPort=10911

#刪除文件時間點,默認凌晨4點
deleteWhen=04

#文件保留時間,默認48 小時
fileReservedTime=120

#commitLog每個文件的大小默認1G
mapedFileSizeCommitLog=1073741824

#ConsumeQueue每個文件默認存30W條,根據業務情況調整
mapedFileSizeConsumeQueue=300000

#destroyMapedFileIntervalForcibly=120000

#redeleteHangedFileInterval=120000
#檢測物理文件磁盤空間
diskMaxUsedSpaceRatio=88

#存儲路徑

storePathRootDir=/usr/local/rocketmq/store

#commitLog存儲路徑

storePathCommitLog=/usr/local/rocketmq/store/commitlog

#消費隊列存儲路徑存儲路徑

storePathConsumeQueue=/usr/local/rocketmq/store/consumequeue

#消息索引存儲路徑

storePathIndex=/usr/local/rocketmq/store/index

#checkpoint文件存儲路徑

storeCheckpoint=/usr/local/rocketmq/store/checkpoint

#abort文件存儲路徑

abortFile=/usr/local/rocketmq/store/abort

#限制的消息大小

maxMessageSize=65536

#flushCommitLogLeastPages=4

#flushConsumeQueueLeastPages=2

#flushCommitLogThoroughInterval=10000

#flushConsumeQueueThoroughInterval=60000

#Broker的角色
#- ASYNC_MASTER 異步複製Master
#- SYNC_MASTER 同步雙寫Master
#- SLAVE
brokerRole=ASYNC_MASTER

#刷盤方式
#- ASYNC_FLUSH 異步刷盤
#- SYNC_FLUSH 同步刷盤
flushDiskType=ASYNC_FLUSH

#checkTransactionMessageEnable=false

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章