
目錄
1、消息隊列的作用與使用場景 2、多個消費者監聽一個隊列時,消息如何分發 3、無法被路由的消息去了哪裡 4、消息在什麼時候會變成Dead Letter(死信) 5、RabbitMQ如何實作延時隊列 6、如何保證消息的可靠性投遞 7、消息幂等性 8、如何在服務的和消費端做限流 9、如何保證消息的順序性 10、RabbitMQ叢集模式和叢集節點類型
來源: msd.misuland.com/pd/3148108429789235368
1 1、消息隊列的作用與使用場景
異步:批量資料異步處理,比如上傳檔案
削峰:高負載任務負載均衡,比如電商秒殺搶購
解耦:串行任務并行化,比如退貨流程解耦
廣播:基于Pub/Sub實作一對多通訊
2 2、多個消費者監聽一個隊列時,消息如何分發
輪詢:預設政策,消息輪流,平均收到消息
公平分發:根據消費者處理能力來分發消息,可以設定prefetch_count來表示有多少消息沒有響應ACK,就不再給這個消費者發送消息
3 3、無法被路由的消息去了哪裡
如果沒有任何設定,因為Routing_key沒有比對,無法被路由的消息會被直接丢棄
解決方案:
- 使用mandatory=true配合ReturnListener實作消息回發
- 聲明交換機時,指定備份交換機
4 4、消息在什麼時候會變成Dead Letter(死信)
- 消費被拒絕并且沒有設定重新入隊:(NACK || Reject)&&requeue==false
- 消息過期(消息或者隊列的TTL設定)
- 消息堆積,并且隊列達到最大長度,先入隊的消息會變成DL(死信)
可以在聲明隊列時,指定一個Dead Letter Exchange,來實作Dead Letter的轉發
5 5、RabbitMQ如何實作延時隊列
- 利用TTL(隊列的消息存活時間或消息存活時間),加上死信交換機
- 先儲存消息到資料庫,用排程器掃描發送(時間不夠精準)
6 6、如何保證消息的可靠性投遞
- 確定投遞到服務端Broker上
- 保證正确的路由
- 消息的持久化存儲
- 消費者應答ACK
- 消費者回調
- 補償機制
7 7、消息幂等性 首先Broker本身沒有消息重複過濾機制 1、生産者方面,可以對每一條消息生成一個msgID,以控制消息重複投遞
// 消息屬性 AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder() .messageId(String.valueOf(UUID.randomUUID())) .build(); // 發送消息 channel.basicPublish("", QUEUE_NAME, properties, msg.getBytes());
2、消費者方面,消息體(比如json封包)中必須攜帶一個業務ID,比如支付id,消費者可以根據支付id去重,避免重複消費8 8、如何在服務的和消費端做限流
- 網關/接入層:其它限流方式
- 服務端(Broker):配置檔案中記憶體和磁盤的控制;隊列的長度無法實作限流
- 消費端:prefetch_count
9 9、如何保證消息的順序性
比如新增門店->綁定産品->激活門店這種對消息順序性要求嚴格的場景
一個隊列隻有一個消費者的情況下才能保證順序性,否則隻能通過全局ID來實作
- 每條消息有一個msgID,關聯的消息擁有同一個parentMsgID
- 可以在消費端實作前一條消息未消費,不處理下一條消息(類似責任鍊設計模式);也可以在生産端實作前一條消息未處理完畢,不釋出下一條消息
10 10、RabbitMQ叢集模式和叢集節點類型 普通模式:
預設模式,以兩個節點(rabbit01、rabbit02)為例來進行說明。對于Queue來說,消息實體隻存在于其中一個節點rabbit01(或者rabbit02),rabbit01和rabbit02兩個節點僅有相同的中繼資料,即隊列的結構。當消息進入rabbit01節點的Queue後,consumer從rabbit02節點消費時,RabbitMQ會臨時在rabbit01、rabbit02間進行消息傳輸,把A中的消息實體取出并經過B發送給consumer。是以consumer應盡量連接配接每一個節點,從中取消 息。即對于同一個邏輯隊列,要在多個節點建立實體Queue。否則無論consumer連rabbit01或rabbit02,出口總 在rabbit01,會産生瓶頸。當rabbit01節點故障後,rabbit02節點無法取到rabbit01節點中還未消費的消息實體。如果做了消息持久化,那麼得等rabbit01節點恢複,然後才可被消費;如果沒有持久化的話,就會産生消息丢失的 現象。
鏡像模式:
把需要的隊列做成鏡像隊列,存在與多個節點屬于RabbitMQ的HA方案。該模式解決了普通模式中的 問題,其實質和普通模式不同之處在于,消息實體會主動在鏡像節點間同步,而不是在用戶端取資料時臨時拉取。該模式帶來的副作用也很明顯,除了降低系統性能外,如果鏡像隊列數量過多,加之大量的消息進入,叢集内部的 網絡帶寬将會被這種同步通訊大大消耗掉。是以在對可靠性要求較高的場合中适用。節點分為兩種:記憶體(RAM):儲存狀态到記憶體(但持久化的隊列和消息還是會儲存到磁盤)。磁盤節點:儲存狀态到記憶體和磁盤。一個叢集中至少需要需要一個磁盤節點。