關于RabbitMQ的一些面試題
目錄
0. 什么是RabbitMQ
1. 延時隊列底層實現
2. 使用RabbitMQ需要注意什么
3. RabbitMQ效率
4. 插入延時隊列的過期時間是單調的麻?
5. 如何確保消息正確地發送至RabbitMQ? 如何確保消息接收方消費了消息?
5.1 發送方確認模式
5.2 接收方確認機制
6. 如何避免消息重復投遞或重復消費?
7. 消息基于什么傳輸?
8、消息如何分發?
9、消息怎么路由?
10、如何確保消息不丟失?
10.1 生產者丟失消息
10.2 RabbitMQ自己丟了數據
10.3 消費者弄丟了數據
11、RabbitMQ的集群
12、使用RabbitMQ有什么好處?
12.1 削峰
12.2 異步
12.3 解耦
13、MQ 的缺點
14、介紹Rabbitmq的手動ACK和自動ACK
參考連接
0. 什么是RabbitMQ
RabbitMQ采用AMQP高級新消息隊列協議的一種消息隊列技術,最大的特點是消費并不需要確保提供方實現,實現了服務之間的高度解耦
1. 延時隊列底層實現
2. 使用RabbitMQ需要注意什么
3. RabbitMQ效率
4. 插入延時隊列的過期時間是單調的麻?
5. 如何確保消息正確地發送至RabbitMQ? 如何確保消息接收方消費了消息?
5.1 發送方確認模式
將信道設置成confirm模式(發送方確認模式),則所有在信道上發布的消息都會被指派一個唯一ID。一旦消息被投遞到目的隊列后,或者消息被寫入磁盤后,信道會發送一個確認給生產者(包括消息的ID)。
如果RabbitMQ發生內部錯誤從而導致消息丟失,會發送一條nack消息。
發送方確認模式是異步的,生產者應用程序在等待確認的同時,可以繼續發送消息。
當確認消息到達生產者應用程序,生產者應用的回調方法就會被觸發來處理確認消息。
5.2 接收方確認機制
消費者接受每一條消息后都必須進行確認,只要有消費者確認了消息,MQ才能安全的把消息從隊列中刪除。
這里并沒有用到超時機制,MQ僅通過Consumer的連接中斷來確認是否需要重新發送消息。也就是說,只要連接不中斷,RabbitMQ給了Consumer足夠長的時間來處理消息。保證了數據的最終一致性。
還有幾種情況:
如果消費者接受到消息,在確認之前斷開了連接或取消訂閱,RabbitMQ會認為消息沒有被分發,然后重新分發給下一個訂閱的消費者。(可能存在消費重復的隱患,需要去重)
如果消費者接受到消息卻沒有確認消息,連接也未斷開,則RabbitMQ認為該消費者繁忙。則不會給該消費者分發更多的消息。
6. 如何避免消息重復投遞或重復消費?
在消息生產時,MQ內部針對每條生產者發送的消息生成一個inner-msg-id,作為去重的依據(消息投遞失敗并重傳),避免重復的消息進入隊列,在消息消費時,要求消息體中 必須要有一個bizID(對于同一個業務全局唯一) 作為去重的依據,避免同一條消息被重復消費。
7. 消息基于什么傳輸?
由于 TCP 連接的創建和銷毀開銷較大,且并發數受系統資源限制,會造成性能瓶頸。RabbitMQ 使用信道的方式來傳輸數據。信道是建立在真實的 TCP 連接內的虛擬連接,且每條 TCP 連接上的信道數量沒有限制。
8、消息如何分發?
一個生產者,多個消費者
多個消費者時,是輪詢機制,依次分發給消費者(每個消費者按順序依次消費)
no_act設置是否確認消息處理完?
no_act = True , 消費者不發送確認信息,RabbitMQ從發送消息隊列后,不管消費者是否處理完,刪除queue
設置no_act=False,RabbitMQ等待消費者的callback處理完,發送確認信息,如果此時消費者down了,則RabbitMQ把消息輪詢發送給下一個消費者,等待確認才會刪除queue
去掉no_act=True,需要在回調函數中新增代碼,手動向RabbitMQ發送確認信息
9、消息怎么路由?
Direct:直連模式
Topic: 轉發模式
Topic 模式下可以使用統配符表示bingKey:’*'表示匹配一個單詞, '#'則表示匹配沒有或者多個單詞。由此可以實現一個queue接收多個路由的消息。
Fanout :廣播模式
廣播模式下,不用理會routing key。Fanout Exchange 會將消息傳遞到 exchange 綁定好的 queue list 上去。
10、如何確保消息不丟失?
10.1 生產者丟失消息
可以選擇使用 RabbitMQ 提供事務功能,就是生產者在發送數據之前開啟事務,然后發送消息,如果消息沒有成功被RabbitMQ接收到,那么生產者會受到異常報錯,這時就可以回滾事物,然后嘗試重新發送;如果收到了消息,那么就可以提交事物。
缺點: RabbitMQ 事務已開啟,就會變為同步阻塞操作,生產者會阻塞等待是否發送成功,太耗性能會造成吞吐量的下降。
還有就是上面的第五點
10.2 RabbitMQ自己丟了數據
持久化
10.3 消費者弄丟了數據
使用 RabbitMQ 提供的 ACK 機制,首先關閉 RabbitMQ 的自動ACK,然后每次在確保處理完這個消息之后,在代碼里手動調用 ACK。這樣就可以避免消息還沒有處理完就ACK。
11、RabbitMQ的集群
12、使用RabbitMQ有什么好處?
12.1 削峰
把消息壓入RabbitMQ中可以緩沖系統壓力。比如現在系統只能接受2000請求,但是一下子有10000個請求過來,那么這個請求就會壓在RabbitMQ中,那么就可以慢慢進行消費了。
12.2 異步
以前是先去發短信,再去發郵件。引入RabbitMQ之后,我們就可以進行在發短信的同時再去發郵箱。
12.3 解耦
當多個系統耦合在一起的時候,系統的消息會發送給連在一起的系統,但是這個消息有些系統可能是不需要的。所以引入了之后,很方便將這個系統進行解耦,每個系統需要的就在消息隊列解耦。
13、MQ 的缺點
雖然能提供削峰,異步,解耦,但是這個還是有很多要考慮的問題,消息丟失,重復消費。
14、介紹Rabbitmq的手動ACK和自動ACK
當消息一旦被消費者接收,隊列中的消息就會被刪除。那么問題來了:RabbitMQ怎么知道消息被接收了呢?
這就要通過消息確認機制(Acknowlege)來實現了。當消費者獲取消息后,會向RabbitMQ發送回執ACK,告知消息已經被接收。不過這種回執ACK分兩種情況:
自動ACK:消息一旦被接收,消費者自動發送ACK
手動ACK:消息接收后,不會發送ACK,需要手動調用
這兩ACK要怎么選擇呢?這需要看消息的重要性:
如果消息不太重要,丟失也沒有影響,那么自動ACK會比較方便
如果消息非常重要,不容丟失。那么最好在消費完成后手動ACK,否則接收消息后就自動ACK,RabbitMQ就會把消息從隊列中刪除。如果此時消費者宕機,那么消息就丟失了。
參考連接
分布式消息中間件-RabbitMQ面試題(必問)
RabbitMQ-解耦、異步、削峰
HTTP RabbitMQ
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。