RabbitMQ的一些總結以及疑問

1、上千萬條消息在mq中積壓了⼏個⼩時還沒解決:

1)先修復consumer的問題,確保其恢復消費速度,然後將現有consumer都停掉;
2)新建⼀個topic,partition是原來的10倍,臨時建⽴好原先10倍或者20倍的queue數量;
3)然後寫⼀個臨時的分發數據的consumer程序,這個程序部署上去消費積壓的數據;
消費之後不做耗時的處理,直接均勻輪詢寫⼊臨時建⽴好的10倍數量的queue;
4)接着臨時徵⽤10倍的機器來部署consumer,每⼀批consumer消費⼀個臨時queue的數據;
5)這種做法相當於是臨時將queue資源和consumer資源擴⼤10倍,以正常的10倍速度來消費數據;
6)等快速消費完積壓數據之後,得恢復原先部署架構,重新⽤原先的consumer機器來消費消息。
總結:

  1. 修復並停掉consumer;
  2. 新建⼀個topic,partition是原來的10倍,建⽴臨時queue,數量是原來的10倍或20倍;
  3. 寫臨時consumer程序,臨時徵⽤10倍的機器去消費數據;
  4. 消費完成之後,恢復原先consumer;

2、rabbitmq設置過期時間,部分消息丟失:

採取批量重導⽅法:將丟失的那批數據查詢導⼊到mq⾥⾯。
3、RabbitMQ 上的⼀個 queue 中存放的 message 是否有數量限制?
可以認爲是⽆限制,因爲限制取決於機器的內存,但是消息過多會導致處理效率的下降。
4、分佈式部署:
RabbitMQ⽆法容忍不同數據中⼼之間⽹絡延遲,但是可以通過3種⽅式實現分佈式部署:Federation和Shovel。

5、如何確保消息正確地發送⾄RabbitMQ?

RabbitMQ使⽤發送⽅確認模式,確保消息正確地發送到RabbitMQ。
發送⽅確認模式:將信道設置成confirm模式(發送⽅確認模式),則所有在信道上發佈的消息都會被指派⼀個唯⼀的
ID。⼀旦消息被投遞到⽬的隊列後,或者消息被寫⼊磁盤後(可持久化的消息),信道會發送⼀個確認給⽣產者(包含消息唯
⼀ID)。如果RabbitMQ發⽣內部錯誤從⽽導致消息丟失,會發送⼀條nack(not acknowledged,未確認)消息。
發送⽅確認模式是異步的,⽣產者應⽤程序在等待確認的同時,可以繼續發送消息。當確認消息到達⽣產者應⽤程序,⽣
產者應⽤程序的回調⽅法就會被觸發來處理確認消息。

6、如何確保消息接收⽅消費了消息?

接收⽅消息確認機制:消費者接收每⼀條消息後都必須進⾏確認(消息接收和消息確認是兩個不同操作)。只有消費者確
認了消息,RabbitMQ才能安全地把消息從隊列中刪除。
這⾥並沒有⽤到超時機制,RabbitMQ僅通過Consumer的連接中斷來確認是否需要重新發送消息。也就是說,只要連接不
中斷,RabbitMQ給了Consumer⾜夠⻓的時間來處理消息。
特殊情況:
1、如果消費者接收到消息,在確認之前斷開了連接或取消訂閱,RabbitMQ會認爲消息沒有被分發,然後重新分發給下⼀
個訂閱的消費者。(可能存在消息重複消費的隱患,需要根據bizId去重)
2、如果消費者接收到消息卻沒有確認消息,連接也未斷開,則RabbitMQ認爲該消費者繁忙,將不會給該消費者分發更多
的消息。

7、如何避免消息重複投遞或重複消費?

在消息⽣產時,MQ內部針對每條⽣產者發送的消息⽣成⼀個inner-msg-id,作爲去重和冪等的依據(消息投遞失敗並重
傳),避免重複的消息進⼊隊列;在消息消費時,要求消息體中必須要有⼀個bizId(對於同⼀業務全局唯⼀,如⽀付ID、訂單
ID、帖⼦ID等)作爲去重和冪等的依據,避免同⼀條消息被重複消費。

8、消息基於什麼傳輸?

由於TCP連接的創建和銷燬開銷較⼤,且併發數受系統資源限制,會造成性能瓶頸。RabbitMQ使⽤信道的⽅式來傳輸數據。信道是建⽴在真實的TCP連接內的虛擬連接,且每條TCP連接上的信道數量沒有限制。
1、RabbitMQ採⽤類似NIO(Non-blocking I/O)做法,選擇TCP連接復⽤,不僅可以減少性能開銷,同時也便於管理。
2、每個線程把持⼀個信道,所以信道服⽤了Connection的TCP連接。同時RabbitMQ可以確保每個線程的私密性,就像擁有
獨⽴的連接⼀樣。

9、如何確保消息不丟失?

消息持久化的前提是:將交換器/隊列的durable屬性設置爲true,表示交換器/隊列是持久交換器/隊列,在服務器崩潰或重
啓之後不需要重新創建交換器/隊列(交換器/隊列會⾃動創建)。
如果消息想要從Rabbit崩潰中恢復,那麼消息必須:
1、在消息發佈前,通過把它的 “投遞模式” 選項設置爲2(持久)來把消息標記成持久化
2、將消息發送到持久交換器
3、消息到達持久隊列
RabbitMQ確保持久性消息能從服務器重啓中恢復的⽅式是,將它們寫⼊磁盤上的⼀個持久化⽇志⽂件,當發佈⼀條持久性消息到持久交換器上時,Rabbit會在消息提交到⽇志⽂件後才發送響應(如果消息路由到了⾮持久隊列,它會⾃動從持久化⽇志中移除)。⼀旦消費者從持久隊列中消費了⼀條持久化消息,RabbitMQ會在持久化⽇志中把這條消息標記爲等待垃圾收集。如果持久化消息在被消費之前RabbitMQ重啓,那麼Rabbit會⾃動重建交換器和隊列(以及綁定),並重播持久化⽇志⽂件中的消息到合適的隊列或者交換器上。

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