2019年12道RabbitMQ高頻面試題你都會了嗎?(含答案解析)

RabbitMQ 面試題

1、什麼是 rabbitmq

2、爲什麼要使用 rabbitmq

3、使用 rabbitmq 的場景

4、如何確保消息正確地發送至 RabbitMQ? 如何確保消息接收方消費了消息?

5.如何避免消息重複投遞或重複消費?

6、消息基於什麼傳輸?

7、消息如何分發?

8、消息怎麼路由?

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

10、使用 RabbitMQ 有什麼好處?

11、RabbitMQ 的集羣

12、mq 的缺點

1、什麼是 rabbitmq

採用 AMQP 高級消息隊列協議的一種消息隊列技術,最大的特點就是消費並不需要確保提供方存在,實現了服務之間的高度解耦

 

2、爲什麼要使用 rabbitmq

(1)在分佈式系統下具備異步,削峯,負載均衡等一系列高級功能;

(2)擁有持久化的機制,進程消息,隊列中的信息也可以保存下來。

(3)實現消費者和生產者之間的解耦。

(4)對於高併發場景下,利用消息隊列可以使得同步訪問變爲串行訪問達到一定量的限流,利於數據庫的操作。

(5)可以使用消息隊列達到異步下單的效果,排隊中,後臺進行邏輯下單。

 

3、使用 rabbitmq 的場景

(1)服務間異步通信

(2)順序消費

(3)定時任務

(4)請求削峯

 

4、如何確保消息正確地發送至 RabbitMQ? 如何確保消息接收方消費了消息?

發送方確認模式

將信道設置成 confirm 模式(發送方確認模式),則所有在信道上發佈的消息都會被指派一個唯一的 ID。

一旦消息被投遞到目的隊列後,或者消息被寫入磁盤後(可持久化的消息),信道會發送一個確認給生產者(包含消息唯一 ID)。

如果 RabbitMQ 發生內部錯誤從而導致消息丟失,會發送一條 nack(notacknowledged,未確認)消息。

發送方確認模式是異步的,生產者應用程序在等待確認的同時,可以繼續發送消息。當確認消息到達生產者應用程序,生產者應用程序的回調方法就會被觸發來處理確認消息。

接收方確認機制

消費者接收每一條消息後都必須進行確認(消息接收和消息確認是兩個不同操作)。只有消費者確認了消息,RabbitMQ 才能安全地把消息從隊列中刪除。

這裏並沒有用到超時機制,RabbitMQ 僅通過 Consumer 的連接中斷來確認是否需要重新發送消息。也就是說,只要連接不中斷,RabbitMQ 給了 Consumer 足夠長的時間來處理消息。保證數據的最終一致性;

下面羅列幾種特殊情況

(1)如果消費者接收到消息,在確認之前斷開了連接或取消訂閱,RabbitMQ 會認爲消息沒有被分發,然後重新分發給下一個訂閱的消費者。(可能存在消息重複消費的隱患,需要去重)

(1)2如果消費者接收到消息卻沒有確認消息,連接也未斷開,則 RabbitMQ 認爲該消費者繁忙,將不會給該消費者分發更多的消息。

5.如何避免消息重複投遞或重複消費?

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

 

6、消息基於什麼傳輸?

由於 TCP 連接的創建和銷燬開銷較大,且併發數受系統資源限制,會造成性能瓶頸。RabbitMQ 使用信道的方式來傳輸數據。信道是建立在真實的 TCP 連接內的虛擬連接,且每條 TCP 連接上的信道數量沒有限制。

 

7、消息如何分發?

若該隊列至少有一個消費者訂閱,消息將以循環(round-robin)的方式發送給消費者。每條消息只會分發給一個訂閱的消費者(前提是消費者能夠正常處理消息並進行確認)。通過路由可實現多消費的功能

 

8、消息怎麼路由?

消息提供方->路由->一至多個隊列消息發佈到交換器時,消息將擁有一個路由鍵(routing key),在消息創建時設定。通過隊列路由鍵,可以把隊列綁定到交換器上。消息到達交換器後,RabbitMQ 會將消息的路由鍵與隊列的路由鍵進行匹配(針對不同的交換器有不同的路由規則);

常用的交換器主要分爲一下三種:

fanout:如果交換器收到消息,將會廣播到所有綁定的隊列上

direct:如果路由鍵完全匹配,消息就被投遞到相應的隊列

topic:可以使來自不同源頭的消息能夠到達同一個隊列。 使用 topic 交換器時,可以使用通配符

 

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

消息持久化,當然前提是隊列必須持久化

RabbitMQ 確保持久性消息能從服務器重啓中恢復的方式是,將它們寫入磁盤上的一個持久化日誌文件,當發佈一條持久性消息到持久交換器上時,Rabbit 會在消息提交到日誌文件後才發送響應。一旦消費者從持久隊列中消費了一條持久化消息,RabbitMQ 會在持久化日誌中把這條消息標記爲等待垃圾收集。如果持久化消息在被消費之前 RabbitMQ 重啓,那麼 Rabbit 會自動重建交換器和隊列(以及綁定),並重新發布持久化日誌文件中的消息到合適的隊列。

 

10、使用 RabbitMQ 有什麼好處?

(1)服務間高度解耦

(2)異步通信性能高

(3)流量削峯

 

11、RabbitMQ 的集羣

鏡像集羣模式

你創建的 queue,無論元數據還是 queue 裏的消息都會存在於多個實例上,然後每次你寫消息到 queue 的時候,都會自動把消息到多個實例的 queue 裏進行消息同步。

好處在於,你任何一個機器宕機了,沒事兒,別的機器都可以用。壞處在於,第一,這個性能開銷也太大了吧,消息同步所有機器,導致網絡帶寬壓力和消耗很重!第二,這麼玩兒,就沒有擴展性可言了,如果某個 queue 負載很重,你加機器,新增的機器也包含了這個 queue 的所有數據,並沒有辦法線性擴展你的 queue

12、mq 的缺點

(1)系統可用性降低

系統引入的外部依賴越多,越容易掛掉,本來你就是 A 系統調用 BCD 三個系統的接口就好了,人 ABCD 四個系統好好的,沒啥問題,你偏加個 MQ 進來,萬一MQ 掛了咋整?MQ 掛了,整套系統崩潰了,你不就完了麼。

(2)系統複雜性提高

硬生生加個 MQ 進來,你怎麼保證消息沒有重複消費?怎麼處理消息丟失的情況?怎麼保證消息傳遞的順序性?頭大頭大,問題一大堆,痛苦不已

(3)一致性問題

A 系統處理完了直接返回成功了,人都以爲你這個請求就成功了;但是問題是,要是 BCD 三個系統那裏,BD 兩個系統寫庫成功了,結果 C 系統寫庫失敗了,咋整?你這數據就不一致了。

所以消息隊列實際是一種非常複雜的架構,你引入它有很多好處,但是也得針對它帶來的壞處做各種額外的技術方案和架構來規避掉,最好之後,你會發現,媽呀,系統複雜度提升了一個數量級,也許是複雜了 10 倍。但是關鍵時刻,用,還是得用的。

 

歡迎大家關注我的公衆號【程序員追風】,2019年多家公司java面試題整理了1000多道400多頁pdf文檔,文章都會在裏面更新,整理的資料也會放在裏面。

 

最後

歡迎大家一起交流,喜歡文章記得關注我點個贊喲,感謝支持!

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