您好,登錄后才能下訂單哦!
這篇文章主要介紹“RabbitMQ面試問答題有哪些”,在日常操作中,相信很多人在RabbitMQ面試問答題有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”RabbitMQ面試問答題有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
其實就是問問你消息隊列都有哪些使用場景,然后你項目里具體是什么場景,說說你在這個場景里用消息隊列是什么?
先說一下消息隊列常見的使用場景吧,其實場景有很多,但是比較核心的有 3 個:解耦、異步、削峰。
解耦:多系統多進程的數據交換,用pub/sub
異步:把大數據量的同步處理改為異步
削峰:一般的A 系統使用 MySQL,扛到每秒 2k 個請求就差不多了,如果每秒請求到 5k 的話,可能就直接把 MySQL 給打死了,導致系統崩潰,用戶也就沒法再使用系統了。如果使用 MQ, 每秒 5k 個請求寫入 MQ,A 系統每秒鐘最多處理 2k 個請求,因為 MySQL 每秒鐘最多處理 2k 個。A 系統從 MQ 中慢慢拉取請求,每秒鐘就拉取 2k 個請求,不要超過自己每秒能處理的最 大請求數量就 ok,這樣下來,哪怕是高峰期的時候,A 系統也絕對不會掛掉,這又設計請求排隊的問題。
優點:解耦、異步、削峰
缺點:
系統可用性降低
系統引入的外部依賴越多,越容易掛掉。
系統復雜度提高
一致性問題
A 系統處理完了直接返回成功了,人都以為你這個請求就成功了;但是問題是,要是 BCD 三個系統那里,BD 兩個系統寫庫成功了,結果 C 系統寫庫失敗了,這數據就不一致了。
RabbitMQ 有三種模式:單機模式、普通集群模式、鏡像集群模式
單機模式不存在高可用。
普通集群模式也不存在高可用性,意思就是在多臺機器上啟動多個 RabbitMQ 實例,每個機器啟動一個。但是你創建的 queue,只會放在一個 RabbitMQ 實例上,但是每個實例都同步 queue 的元數據(元數據可以認為是 queue 的一些配置信息,通過元數據,可以找到 queue 所在實例)。你消費的時候,實際上如果連接到了另外一個實例,那么那個實例會從 queue 所在實例上 拉取數據過來。這種方式確實很麻煩,也不怎么好,沒做到所謂的分布式,就是個普通集群。因為這導致你要么消費者每次隨機連接一個實例然后拉取數據,要么固定連接那個 queue 所在實 例消費數據,前者有數據拉取的開銷,后者導致單實例性能瓶頸。而且如果那個放 queue 的實例宕機了,會導致接下來其他實例就無法從那個實例拉取,如果你開啟了消息持久化,讓 RabbitMQ 落地存儲消息的話,消息不一定會丟,得等這個實例恢復了,然后才可以繼續從這個 queue 拉取數據。
鏡像集群模式的策略是高可用策略,指定的時候可以要求數據同步到所有節點的,也可以要求同步到指定數量的節點,再次創建 queue 的時候,應用這個策略,就會自動將數據同步到其他的 節點上去了。
其實本質針對的場景,都是說,可能你的消費端出了問題,不消費了;或者消費的速度極其慢,造成消息堆積了,MQ存儲快要爆了,甚至開始過期失效刪除數據了。
針對這個問題可以有事前、事中、事后三種處理
事前:開發預警程序,監控最大的可堆積消息數,超過就發預警消息(比如短信),不要等出生產事故了再處理。
事中:看看消費端是不是故障停止了,緊急重啟。
事后:需要對消費端緊急擴容 ,增加處理消費者進程,如擴充10倍處理,但其實這也有個問題,即數據庫的吞吐是有限制的,如果是消費到數據庫也是沒辦法巨量擴容的,所以還是要在吞吐能力支持下老老實實的泄洪消 費。所以事前預防還是最重要的。否則出發刪除過期數據,那就需要再重寫生產消息的程序,重新產生消息。
需要考慮3個可能丟數據的地方:生產端、隊列本身、消費端
(1)生產端:開啟事務(不推薦,太耗性能降低吞吐),推薦開啟 confirm 模式,在生產者那里設置開啟 confirm 模式之后,你每次寫的消息都會分配一個唯一的 id,然后如果寫入了RabbitMQ 中,RabbitMQ 會給你回傳一個 ack 消息,告訴你說這個消息 ok 了。如果 RabbitMQ 沒能處理這個消息,會回調你的一個 nack 接口,告訴你這個消息接收失敗,你可以重試。而 且你可以結合這個機制自己在內存里維護每個消息 id 的狀態,如果超過一定時間還沒接收到這個消息的回調,那么你可以重發。
(2)隊列本身:就是 RabbitMQ 自己弄丟了數據,這個你必須開啟 RabbitMQ 的持久化,就是消息寫入之后會持久化到磁盤,哪怕是 RabbitMQ 自己掛了,恢復之后會自動讀取之前存儲的數據,一般數據不會丟。
設置持久化有兩個步驟:
創建 queue 的時候將其設置為持久化,這樣就可以保證 RabbitMQ 持久化 queue 的元數據,但是它是不會持久化 queue 里的數據的。
第二個是發送消息的時候將消息的 deliveryMode 設置為 2。就是將消息設置為持久化的,此時 RabbitMQ 就會將消息持久化到磁盤上去。
(3)消費端:其實和kafka的原理很類似,kafka即手動提交offsize。用RabbitMQ 提供的 ack 機制,簡單來說,就是你必須關閉 RabbitMQ 的自動 ack,通過自己的一個 api 來調用就行,然后每次你自己代碼里確保處理完的時候,再在程序里 ack。這樣的話,如果你還沒處理完,不就沒有 ack 了?那 RabbitMQ 就認為你還沒處理完,這個時候 RabbitMQ 會把這個消費分配給別 的 consumer 去處理,消息是不會丟的。
這個需要靈活作答,考察的是思考力,因為消費的場景有很多,有數據庫、有緩存、有第三方接口
(1)比如針對數據庫,你拿到這個消息做數據庫的insert操作。那就容易了,給這個消息做一個唯一主鍵(或者UUID),那么就算出現重復消費的情況,就會導致主鍵沖突,避免數據庫出現臟數據。
(2)再比如redis緩存,你拿到這個消息做redis的set的操作,那就容易了,不用解決,因為你無論set幾次結果都是一樣的,set操作本來就算冪等操作。
(3)再比如第三方接口,需要確定兩點,第三方接口程序是有去重能力的,那么臟一點直接丟數據過去,如果沒有去重能力,還是需要我們來寫程序去重,就是第2點的辦法。
節點的存儲類型分為兩種:
磁盤節點
內存節點
磁盤節點就是配置信息和元信息存儲在磁盤上,內存節點把這些信息存儲在內存中,當然內次節點的性能是大大超越磁盤節點的。
單節點系統必須是磁盤節點,否則每次你重啟RabbitMQ之后所有的系統配置信息都會丟失。
RabbitMQ要求集群中至少有一個磁盤節點,當節點加入和離開集群時,必須通知磁盤節點。
到此,關于“RabbitMQ面試問答題有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。