日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

RabbitMQ面试题及答案

發布時間:2025/3/21 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RabbitMQ面试题及答案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是RabbitMQ?為什么使用RabbitMQ?

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

可以用它來:解耦、異步、削峰。

為什么要使用rabbitmq

  • 在分布式系統下具備異步,削峰,負載均衡等一系列高級功能
  • 擁有持久化的機制,進程消息,隊列中的信息也可以保存下來
  • 實現消費者和生產者之間的解耦
  • 對于高并發場景下,利用消息隊列可以使得同步訪問變為串行訪問達到一定量的限流,利于數據庫的操作
  • 可以使用消息隊列達到異步下單的效果,排隊中,后臺進行邏輯下單
  • 使用rabbitmq的場景

    • 服務間異步通信
    • 順序消費
    • 定時任務
    • 請求削峰

    RabbitMQ有什么優缺點?

    優點:

    • 解耦
    • 系統A在代碼中直接調用系統B和系統C的代碼,如果將來D系統接入,系統A還需要修改代碼,過于麻煩!

    • 異步
    • 將消息寫入消息隊列,非必要的業務邏輯以異步的方式運行,加快響應速度

    • 削峰
    • 并發量大的時候,所有的請求直接懟到數據庫,造成數據庫連接異常

    缺點:

    • 降低了系統的穩定性

    • 本來系統運行好好的,現在你非要加入個消息隊列進去,那消息隊列掛了,你的系統不是呵呵了。因此,系統可用性會降低

    • 增加了系統的復雜性

    • 加入了消息隊列,要多考慮很多方面的問題,比如:一致性問題、如何保證消息不被重復消費、如何保證消息可靠性傳輸等。因此,需要考慮的東西更多,復雜性增大

    線程Queue,進程Queue和RabbitMQ區別

    • 進程Queue用于父進程與子進程(或同一父進程中多個子進程)間數據傳遞
    • python自己的多個進程間交換數據或者與其他語言(如Java)進程queue就無能為力
    • RabbitMQ就是這樣一個可以在不同程序間共享數據的代理

    RabbitMQ 中的 broker 是指什么?cluster 又是指什么?

    • broker 是指一個或多個 erlang node 的邏輯分組,且 node 上運行著 RabbitMQ 應用程序
    • cluster 是在 broker 的基礎之上,增加了 node 之間共享元數據的約束

    RabbitMQ 概念里的 channel、exchange 和 queue 是邏輯概念,還是對應著進程實體?分別起什么作用?

    • queue 具有自己的 erlang 進程
    • exchange 內部實現為保存 binding 關系的查找表
    • channel 是實際進行路由工作的實體,即負責按照 routing_key 將 message 投遞給 queue

    由 AMQP 協議描述可知,channel 是真實 TCP 連接之上的虛擬連接,所有 AMQP 命令都是通過 channel 發送的,且每一個 channel 有唯一的 ID。一個 channel 只能被單獨一個操作系統線程使用,故投遞到特定 channel 上的 message 是有順序的。但一個操作系統線程上允許使用多個 channel

    消息基于什么傳輸?

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

    消息如何分發?

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

    如何確保消息正確地發送至RabbitMQ?

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

    如何確保消息接收方消費了消息?

    • 接收方消息確認機制:消費者接收每一條消息后都必須進行確認(消息接收和消息確認是兩個不同操作)
    • 只有消費者確認了消息,RabbitMQ才能安全地把消息從隊列中刪除
      這里并沒有用到超時機制,RabbitMQ僅通過Consumer的連接中斷來確認是否需要重新發送消息
    • 也就是說,只要連接不中斷,RabbitMQ給了Consumer足夠長的時間來處理消息

    下面列出幾種特殊情況:

    • 如果消費者接收到消息,在確認之前斷開了連接或取消訂閱,RabbitMQ會認為消息沒有被分發,然后重新分發給下一個訂閱的消費者。(可能存在消息重復消費的隱患,需要根據bizId去重)
    • 如果消費者接收到消息卻沒有確認消息,連接也未斷開,則RabbitMQ認為該消費者繁忙,將不會給該消費者分發更多的消息

    如何保證RabbitMQ的高可用?

    答:沒有哪個項目會搭建一臺RabbitMQ服務器提供服務,風險太大;

    如何保證RabbitMQ不被重復消費?

    先說為什么會重復消費:正常情況下,消費者在消費消息的時候,消費完畢后,會發送一個確認消息給消息隊列,消息隊列就知道該消息被消費了,就會將該消息從消息隊列中刪除;

    但是因為網絡傳輸等等故障,確認信息沒有傳送到消息隊列,導致消息隊列不知道自己已經消費過該消息了,再次將消息分發給其他的消費者

    • 在消息生產時,MQ內部針對每條生產者發送的消息生成一個inner-msg-id,作為去重的依據(消息投遞失敗并重傳),避免重復的消息進入隊列
    • 在消息消費時,要求消息體中必須要有一個bizId(對于同一業務全局唯一,如支付ID、訂單ID、帖子ID等)作為去重的依據,避免同一條消息被重復消費
    • 保證消息的唯一性,就算是多次傳輸,不要讓消息的多次消費帶來影響;保證消息等冪性
    • 在寫入消息隊列的數據做唯一標示,消費消息時,根據唯一標識判斷是否消費過

    如何保證RabbitMQ消息的可靠傳輸?

    答:消息不可靠的情況可能是消息丟失,劫持等原因;

    丟失又分為:

    • 生產者丟失消息
    • 消息列表丟失消息
    • 消費者丟失消息

    生產者丟失消息:
    從生產者弄丟數據這個角度來看,RabbitMQ提供transaction和confirm模式來確保生產者不丟消息;

    transaction機制就是說:

    • 發送消息前,開啟事務(channel.txSelect()),然后發送消息,如果發送過程中出現什么異常,事務就會回滾(channel.txRollback())
    • 如果發送成功則提交事務(channel.txCommit())
    • 這種方式有個缺點:吞吐量下降

    confirm模式用的居多:一旦channel進入confirm模式,所有在該信道上發布的消息都將會被指派一個唯一的ID(從1開始),一旦消息被投遞到所有匹配的隊列之后;

    rabbitMQ就會發送一個ACK給生產者(包含消息的唯一ID),這就使得生產者知道消息已經正確到達目的隊列了;

    如果rabbitMQ沒能處理該消息,則會發送一個Nack消息給你,你可以進行重試操作。

    消息列表丟失消息:
    消息持久化。

    處理消息隊列丟數據的情況,一般是開啟持久化磁盤的配置。

    這個持久化配置可以和confirm機制配合使用,你可以在消息持久化磁盤后,再給生產者發送一個Ack信號。

    這樣,如果消息持久化磁盤之前,rabbitMQ陣亡了,那么生產者收不到Ack信號,生產者會自動重發。

    那么如何持久化呢?

    這里順便說一下吧,其實也很容易,就下面兩步

    將queue的持久化標識durable設置為true,則代表是一個持久的隊列
    發送消息的時候將deliveryMode=2
    這樣設置以后,即使rabbitMQ掛了,重啟后也能恢復數據

    消費者丟失消息:
    消費者丟數據一般是因為采用了自動確認消息模式,改為手動確認消息即可!

    消費者在收到消息之后,處理消息之前,會自動回復RabbitMQ已收到消息;

    如果這時處理消息失敗,就會丟失該消息;

    解決方案:處理消息成功后,手動回復確認消息。

    如何保證RabbitMQ消息的順序性?

    單線程消費保證消息的順序性;對消息進行編號,消費者處理消息是根據編號處理消息

    消息怎么路由?

    從概念上來說,消息路由必須有三部分:交換器、路由、綁定
    生產者把消息發布到交換器上;綁定決定了消息如何從路由器路由到特定的隊列;消息最終到達隊列,并被消費者接收。

    消息發布到交換器時,消息將擁有一個路由鍵(routing key),在消息創建時設定。
    通過隊列路由鍵,可以把隊列綁定到交換器上。

    消息到達交換器后,RabbitMQ會將消息的路由鍵與隊列的路由鍵進行匹配(針對不同的交換器有不同的路由規則)。如果能夠匹配到隊列,則消息會投遞到相應隊列中;如果不能匹配到任何隊列,消息將進入 “黑洞”。

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

    • direct:如果路由鍵完全匹配,消息就被投遞到相應的隊列
    • fanout:如果交換器收到消息,將會廣播到所有綁定的隊列上
    • topic:可以使來自不同源頭的消息能夠到達同一個隊列。使用topic交換器時,可以使用通配符。比如:“*” 匹配特定位置的任意文本, “.” 把路由鍵分為了幾部分,“#” 匹配所有規則等。

    特別注意:發往topic交換器的消息不能隨意的設置選擇鍵(routing_key),必須是由"."隔開的一系列的標識符組成。

    什么是元數據?元數據分為哪些類型?包括哪些內容?與 cluster 相關的元數據有哪些?元數據是如何保存的?元數據在 cluster 中是如何分布的?

    在非 cluster 模式下:

    元數據主要分為

    • Queue 元數據(queue 名字和屬性等)
    • Exchange元數據(exchange 名字、類型和屬性等)
    • Binding 元數據(存放路由關系的查找表)
    • Vhost元數據(vhost 范圍內針對前三者的名字空間約束和安全屬性設置)

    在 cluster 模式下:

    還包括 cluster 中 node 位置信息和 node 關系信息
    元數據按照 erlang node 的類型確定是僅保存于 RAM 中,還是同時保存在 RAM 和 disk 上。元數據在 cluster 中是全 node 分布的。

    在單node 系統和多 node 構成的 cluster 系統中聲明 queue、exchange ,以及進行 binding 會有什么不同?

    當你在單 node 上聲明 queue 時,只要該 node 上相關元數據進行了變更,你就會得到 Queue.Declare-ok 回應;而在 cluster 上聲明 queue ,則要求 cluster 上的全部 node 都要進行元數據成功更新,才會得到 Queue.Declare-ok 回應。另外,若 node 類型為 RAM node 則變更的數據僅保存在內存中,若類型為 disk node 則還要變更保存在磁盤上的數據。

    死信隊列&死信交換器:DLX 全稱(Dead-Letter-Exchange),稱之為死信交換器,當消息變成一個死信之后,如果這個消息所在的隊列存在x-dead-letter-exchange參數,那么它會被發送到x-dead-letter-exchange對應值的交換器上,這個交換器就稱之為死信交換器,與這個死信交換器綁定的隊列就是死信隊列

    消息在什么時候會變成死信?

    • 消息拒絕并且沒有設置重新入隊
    • 消息過期
    • 消息堆積,并且隊列達到最大長度,先入隊的消息會變成DL

    總結

    以上是生活随笔為你收集整理的RabbitMQ面试题及答案的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。