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文件,文章都會在裡面更新,整理的資料也會放在裡面。
最後
歡迎大家一起交流,喜歡文章記得關注我點個贊喲,感謝支援!