Rocketmq簡介及核心概念詳解(一)

一、rocketmq簡介

  • rocketmq是一款分佈式、隊列模型的消息中間件,由阿里巴巴研發借鑑參考了JMS規範MQ實習,更參考了優秀的開源消息中間件kafka,並結合阿里巴巴的實際業務需求,在天貓雙十一的場景,實現業務消峯,分佈式事務的優秀框架。
  • 底層代碼編寫清晰優秀,採用Netty NIOl框架實現數據通信。
  • 3.X版本棄用Zookeeper,內部使用更輕量級的NameServer進行網絡路由,提供了服務性能,並支持消息失敗重試機制。
  • 支持集羣模式、消費者負載均衡、水平擴展能力,支持廣播模式。
  • 採用零拷貝原理,順序寫盤、支持億級消息堆積能力。
  • 提供豐富的消息機制,比如順序消息、事務消息。

二、核心概念講解

1.專業術語

  • Producer: 消息生成者,負責消息產生,由業務系統負責產生。
  • Consumer:消息消費者,負責消費消費,由後臺業務系統負責異步消費。
  • Push Consumer:Consumer的一種,應用通常向Consumer對象註冊一個Listener接口,一旦接收到消息,Consumer對象立刻回調Listener接口方法。
  • Pull Consumer:Consumer的一種,應用通常主動調用Consumer的拉消息方法從Broker拉消息,主動權由應用控制。
  • Producer Group:一類producer的集合名稱,這類Producer通常發送一類消息,且發送邏輯。
  • Consumer Group:一類Consumer的集合名稱,這類Consumer通常消費一類消息,且發送邏輯。
  • Broker:消息中轉角色,負責存儲消息,轉發消息,一般也稱爲Server。
  • 集羣消費:一個Consumer Group中的Consumer實例平均分攤消費消息。例如某個Topic有9條消息,其中一個Consumer Group有3個 實例(可能是3個進程或3臺機器),那麼每隔實例只消費其中的3條消費。
  • 廣播消費:一條消息被多個Consumer消息,即使這些 Consumer屬於同一個 Consumer Group,消息也會被Consumer Group中的每隔 Consumer都消費一次。
  • 順序消費:指消息的消費順序和產生順序相同,在有些業務邏輯 下 ,必須保證順序。比如訂單的生成、付款、發貨,這3個消息必須按順序處理才行。

三、rocketmq應用場景

         分佈式開放消息系統(RocketMQ)的原理與實踐

四、rocketmq可視化管理控制檯代建

1. 下載開源的rocketmq-externals項目:https://github.com/apache/rocketmq-externals

2. 找到rocketmq-console,先編輯一下rocketmq-console裏面的application.properties文件,將項目使用的rocketmq.config.namesrvAddr配置上去(或者在項目啓動時,以參數的形式配進去)

server.contextPath=
server.port=8082
#spring.application.index=true
spring.application.name=rocketmq-console
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
logging.config=classpath:logback.xml
#if this value is empty,use env value rocketmq.config.namesrvAddr  NAMESRV_ADDR | now, you can set it in ops page.default localhost:9876
rocketmq.config.namesrvAddr=127.0.0.1:9876
#if you use rocketmq version < 3.5.8, rocketmq.config.isVIPChannel should be false.default true
rocketmq.config.isVIPChannel=
#rocketmq-console's data path:dashboard/monitor
rocketmq.config.dataPath=/tmp/rocketmq-console/data
#set it false if you don't want use dashboard.default true
rocketmq.config.enableDashBoardCollect=true

3.將rocktmq-console打成jar包,得到rocketmq-console-ng-1.0.0.jar

mvn clean package -Dmaven.test.skip=true

4.運行jar包,啓動項目(在本地可以直接導入項目到IDEA啓動項目),這裏也可以設置rocketmq.config.namesrvAdd

java -jar rocketmq-console-ng-1.0.0.jar --server.port=12581 --rocketmq.config.namesrvAddr=127.0.0.1:9876

5.控制檯界面如下:

6.參考博客 :https://www.cnblogs.com/miaoying/p/10319840.html

五、rocketmq項目搭建

參考官網:http://rocketmq.apache.org/docs/quick-start/

步驟如下:

1.環境:IDEA2019、Maven、JDK1.8(由於Rocketmq項目基於SpringBoot)

2.下載地址:https://www.apache.org/dyn/closer.cgi?path=rocketmq/4.4.0/rocketmq-all-4.4.0-bin-release.zip

3.配置環境變量:

      變量名:ROCKETMQ_HOME

      變量值:F:\rocketmq-all-4.4.0-bin-release

4.啓動nameserver命令爲: start mqnamesrv.cmd    

   啓動broker命令爲:   start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true

5.在IDEA中創建Producer和consumer實現消息通信

Demo案例演示

consumer消費者----配置參數

consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET):Consumer啓動後,默認從什麼位置開發消費,默認爲CONSUME_FROM_LAST_OFFSET

consumer.setAllocateMessageQueueStrategy():設置負載均衡算法實現策略

consumer.setSubscription():設置訂閱關係

consumer.setMessageListener():設置消息監聽

consumer.setOffsetStore():設置消息進度存儲

consumer.setConsumeThreadMax():設置消費線程的最大數量,默認爲64個線程

consumer.setConsumeThreadMin():設置消費線程的最小數量,默認爲20個線程

consumer.setPullThresholdForQueue():本地隊列緩存消息最大數,默認爲1000

consumer.setConsumeMessageBatchMaxSize():批量消費消息,一次消費多少條消息,默認爲1條

consumer.setPullBatchSize():批量拉取消息,一次性最多拉取多少條消息,默認爲32條

consumer.setPullInterval():設置消息拉取間隔,默認爲0

consumer端應用

/**
 * 源碼分析DefaultMQPushConsumer的處理流程:
 * DefaultMQPushConsumer主要功能實現在DefaultMQPushConsumerImpl類中
 * 處理消息是在:pullMessage()方法中的PullCallBack()方法中
 */
public class Consumer {

    public static void main(String[] args) throws InterruptedException, MQClientException {
        /**
         * 1.使用消費者組名稱進行實例化(消費者類型:DefaultMQPushConsumer,DefaultMQPullConsumer)
         * 2.同一個GroupName下的多個消費者Consumer可以提高併發處理能力,GroupName需要和消息模式(MessageModel)配合使用
         * 3.RocketMQ支持兩種消息模式:
         *      Clusting:一個Consumer只能消費同一個GroupName裏面的一部分消息,從而實現負載均衡
         *      Broadcasting:一個Consumer可以消費GroupName裏面的所有消息
         */
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("please_rename_unique_group_name");
        /**
         * 指定nameserver的地址和端口號,可以填寫多個使用分號隔開。例如:172.22.41.203;172.21.42.204:9876
         * 達到消除單點故障
         */
        consumer.setNamesrvAddr("localhost:9876");

        /**
         * 消費者訂閱消費主題,可以訂閱一個或多個,"null"或"*"表示訂閱多個主題
         * consumer.subscribe("TopicTest", "tag1||tag2||tagn");
         */
        consumer.subscribe("TopicTest", "*");
        // Register callback to execute on arrival of messages fetched from brokers.
        consumer.registerMessageListener(new MessageListenerConcurrently() {

            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
                                                            ConsumeConcurrentlyContext context) {
                for (MessageExt msg :msgs) {
                    System.out.println(msg);
                }
                //System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msgs);
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        //啓動消費者
        consumer.start();
        System.out.printf("Consumer Started.%n");
    }
}

 producer生產者----配置參數

producer.createTopic():在發送消息時,自動創建服務器不存在的topic,需要指定key

producer.setDefaultTopicQueueNums():在發送消息時,自動創建服務器不存在的topic,默認創建隊列數爲4

producer.send():設置發送消息超時時間,單位爲毫秒

producer.setCompressMsgBodyOverHowmuch():發送消息體超過多大進行壓縮(Consumer收到消息自動壓縮),默認爲1024*4,單位字節

producer.setRetryTimesWhenSendFailed():設置生產者發送消息重試次數,默認重試2次

producer.setMaxMessageSize():設置發送消息的大小,默認 maxMessageSize = 1024 * 1024 * 4; // 4M,如果超過最大設置就會報異常。

producer端應用

/**
 * Consumer和Producer都必須設置Topic,GroupName,NameServer地址以及端口號
 * 最後再進入發送和接收邏輯
 */
public class SyncProducer {

    public static void main(String[] args) throws Exception {
        //使用生產者組名稱進行實例化
        DefaultMQProducer producer = new
                DefaultMQProducer("please_rename_unique_group_name");
        //指定nameserver的地址
        producer.setNamesrvAddr("localhost:9876");
        //啓動生產者
        producer.start();
        for (int i = 0; i < 3; i++) {
            //創建消息實例,指定topic、tag、消息內容
            //topic:只允許是^[%|a-zA-Z0-9_-]+$組成的字符串,不能是漢字
            Message msg = new Message("TopicTest",
                    "TagA",
                    ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET)
            );
            //生產將消息發送給一個broker對象處理
            SendResult sendResult = producer.send(msg);
            System.out.println("發送對象信息爲"+JSON.toJSONString(sendResult));
        }
        //關閉生產者實例後此對象不再使用
        //producer.shutdown();
    }
}

 

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