ROCKETMQ學習總結1入門

MQ 作用:應用解耦 、流量削峯 、數據分發

常見的MQ產品包括Kafka、ActiveMQ、RabbitMQ、RocketMQ。

RocketMQ組成角色:

Producer:消息的發送者; Consumer:消息接收者; Broker:暫存和傳輸消息; NameServer:管理Broker; Topic:區分消息的種類; Message Queue:相當於是Topic的分區;用於並行發送和接收消息 。

高可用的保障:集羣搭建:單Master模式、多Master模式、多Master多Slave模式(異步:主備有短暫消息延遲 )、多Master多Slave模式(同步:只有主備都寫成功,才嚮應用返回成功,可用性高但性能比異步低10%左右 )

集羣工作流程:

  1. 啓動NameServer,NameServer起來後監聽端口,等待Broker、Producer、Consumer連上來,相當於一個路由控制中心。

  2. Broker啓動,跟所有的NameServer保持長連接,定時發送心跳包。心跳包中包含當前Broker信息(IP+端口等)以及存儲所有Topic信息。註冊成功後,NameServer集羣中就有Topic跟Broker的映射關係。

  3. 收發消息前,先創建Topic,創建Topic時需要指定該Topic要存儲在哪些Broker上,也可以在發送消息時自動創建Topic。

  4. Producer發送消息,啓動時先跟NameServer集羣中的其中一臺建立長連接,並從NameServer中獲取當前發送的Topic存在哪些Broker上,輪詢從隊列列表中選擇一個隊列,然後與隊列所在的Broker建立長連接從而向Broker發消息。

  5. Consumer跟Producer類似,跟其中一臺NameServer建立長連接,獲取當前訂閱Topic存在哪些Broker上,然後直接跟Broker建立連接通道,開始消費消息。

集羣控制檯:rocketmq-console

消息發送基本步驟:

1.創建消息生產者producer,並制定生產者組名
2.指定Nameserver地址
3.啓動producer
4.創建消息對象,指定主題Topic、Tag和消息體
5.發送消息
6.關閉生產者producer

1.創建消費者Consumer,制定消費者組名
2.指定Nameserver地址
3.訂閱主題Topic和Tag
4.設置回調函數,處理消息
5.啓動消費者consumer

發送消息:

1、同步方式發送消息:producer.send(msg);

2、異步方式發送消息:producer.send(msg, new SendCallback() {處理異步返回} )

3、發送單向消息:producer.sendOneway(msg);

消息消費:

1)負載均衡模式:每個消費者處理的消息不同:consumer.setMessageModel(MessageModel.CLUSTERING);

2)廣播模式:每個消費者消費的消息都是相同的 consumer.setMessageModel(MessageModel.BROADCASTING);

// 註冊回調函數,處理消息
consumer.registerMessageListener(new MessageListenerConcurrently() {}

 

增強的消息發送消費模式:順序消息、延時消息、批量消息、過濾消息、事務消息

1、順序消息:RocketMQ可以嚴格的保證消息有序,可以分爲分區有序或者全局有序。 默認的情況下消息發送會採取Round Robin輪詢方式把消息發送到不同的queue(分區隊列), 消費消息的時候從多個queue上拉取消息無法保證有序所以要控制發送的順序消息只依次發送到同一個queue中,消費的時候只從這個queue上依次拉取,則就保證了順序。全局有序:發送和消費參與的queue只有一個;分區有序:多個queue參與。

方式:producer.send(msg, new MessageQueueSelector(List<MessageQueue> mqs, Message msg, Object arg) {實現MessageQueueSelector中的select方法返回需要進入的MessageQueue},Object arg) {};訂單號相同的消息會被先後發送到同一個隊列 select方法內對訂單號取模計算queue;

設置Consumer第一次啓動是從隊列頭部開始消費還是隊列尾部開始消費, 如果非第一次啓動,那麼按照上次消費的位置繼續消費
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);

consumer.subscribe("TopicTest", "TagA || TagC || TagD");// 訂閱Topics

consumer.registerMessageListener(new MessageListenerOrderly() {// 每個queue有唯一的consume線程來消費, 訂單對每個queue(分區)有序}

延時消費:

message.setDelayTimeLevel(3);// 設置延時等級3,這個消息將在10s之後發送(現在只支持固定的幾個時間,詳看delayTimeLevel)
producer.send(message); // 發送消息

 // 消費者註冊消息監聽者
  consumer.registerMessageListener(new MessageListenerConcurrently() {XXX}

注意:現在RocketMq並不支持任意時間的延時,需要設置幾個固定的延時等級,從1s到2h分別對應着等級1到18 :

private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h";

批量消息:

批量消息應該有相同的topic ,一批消息的總大小不應超過4MB。

List<Message> messages = new ArrayList<>();

messages .add(msg).add(msg).....

producer.send(messages);

過濾消息:

TAG 過濾、SQL過濾。只有使用push模式的消費者才能用使用SQL92標準的sql語句

// 設置一些屬性
msg.putUserProperty("a", String.valueOf(i));
SendResult sendResult = producer.send(msg);

// 只有訂閱的消息有這個屬性a, a >=0 and a <= 3
consumer.subscribe("TopicTest", MessageSelector.bySql("a between 0 and 3");
consumer.registerMessageListener(new MessageListenerConcurrently() {XXX};

事務消息:

實現機制:

1、事務消息發送及提交:(1) 發送消息(half消息)。(2) 服務端響應消息寫入結果。(3) 根據發送結果執行本地事務(如果寫入失敗,此時half消息對業務不可見,本地邏輯不執行)。(4) 根據本地事務狀態執行Commit或者Rollback(Commit操作生成消息索引,消息對消費者可見)

2、事務補償(解決消息Commit或者Rollback發生超時或者失敗的情況):(1) 對沒有Commit/Rollback的事務消息(pending狀態的消息),從服務端發起一次“回查”(2) Producer收到回查消息,檢查回查消息對應的本地事務的狀態(3) 根據本地事務狀態,重新Commit或者Rollback。

事務消息共有三種狀態,提交狀態(允許消費 )、回滾狀態(已刪除消息)、中間狀態 (需要檢查消息隊列來確定狀態 )

/創建事務監聽器
TransactionListener transactionListener = new TransactionListenerImpl();
//創建消息生產者
TransactionMQProducer producer = new TransactionMQProducer("group6");

producer.setTransactionListener(transactionListener);

//啓動消息生產者
producer.start();

其中TransactionListenerImpl實現接口TransactionListener,它返回前一節中提到的三個事務狀態之一,檢查本地事務狀態

限制:不支持延時消息和批量消息;默認單個消息的檢查次數限制爲 15 次,檢查某條消息超過 N 次的話( N = transactionCheckMax ) 則 Broker 將丟棄此消息,並在默認情況下同時打印錯誤日誌。用戶可以通過重寫 AbstractTransactionCheckListener 類來修改這個行爲;事務消息的生產者 ID 不能與其他類型消息的生產者 ID 共享。與其他類型的消息不同,事務消息允許反向查詢、MQ服務器能通過它們的生產者 ID 查詢到消費者。

 

 

 

 

 

 

 

 

 

 

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