一、爲何要引入MQ系統,直接讀寫數據庫不行嗎?
其實就是問問你消息隊列都有哪些使用場景,而後你項目裏具體是什麼場景,說說你在這個場景裏用消息隊列是什麼?html
面試官問你這個問題,指望的一個回答是說,大家公司有個什麼業務場景,這個業務場景有個什麼技術挑戰,若是不用 MQ 可能會很麻煩,可是你如今用了 MQ 以後帶給了你不少的好處。java
先說一下消息隊列常見的使用場景吧,其實場景有不少,可是比較核心的有 3 個:解耦、異步、削峯。
解耦:多系統多進程的數據交換,用pub/sub
異步:把大數據量的同步處理改成異步
削峯:通常的A 系統使用 MySQL,扛到每秒 2k 個請求就差很少了,若是每秒請求到 5k 的話,可能就直接把 MySQL 給打死了,致使系統崩潰,用戶也就無法再使用系統了。若是使用 MQ, 每秒 5k 個請求寫入 MQ,A 系統每秒鐘最多處理 2k 個請求,由於 MySQL 每秒鐘最多處理 2k 個。A 系統從 MQ 中慢慢拉取請求,每秒鐘就拉取 2k 個請求,不要超過本身每秒能處理的最 大請求數量就 ok,這樣下來,哪怕是高峯期的時候,A 系統也絕對不會掛掉,這又設計請求排隊的問題。git
二、消息隊列有什麼優缺點?
優勢:解耦、異步、削峯
缺點:
系統可用性下降
系統引入的外部依賴越多,越容易掛掉。原本你就是 A 系統調用 BCD 三個系統的接口就行了,人 ABCD 四個系統好好的,沒啥問題,你偏加個 MQ 進來,萬一 MQ 掛了咋整,MQ 一掛,整套
系統崩潰的,你不就完了?github
系統複雜度提升
硬生生加個 MQ 進來,你怎麼保證消息沒有重複消費?怎麼處理消息丟失的狀況?怎麼保證消息傳遞的順序性?頭大頭大,問題一大堆,痛苦不已。面試
一致性問題
A 系統處理完了直接返回成功了,人都覺得你這個請求就成功了;可是問題是,要是 BCD 三個系統那裏,BD 兩個系統寫庫成功了,結果 C 系統寫庫失敗了,咋整?你這數據就不一致了。redis
三、Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什麼優缺點?
https://blog.csdn.net/Dome_/article/details/84990563數據庫
四、RabbitMQ 的高可用性如何保證?
RabbitMQ 有三種模式:單機模式、普通集羣模式、鏡像集羣模式
單機模式不存在高可用。
普通集羣模式也不存在高可用性,意思就是在多臺機器上啓動多個 RabbitMQ 實例,每一個機器啓動一個。可是你建立的 queue,只會放在一個 RabbitMQ 實例上,可是每一個實例都同步 queue 的元數據(元數據能夠認爲是 queue 的一些配置信息,經過元數據,能夠找到 queue 所在實例)。你消費的時候,實際上若是鏈接到了另一個實例,那麼那個實例會從 queue 所在實例上 拉取數據過來。這種方式確實很麻煩,也不怎麼好,沒作到所謂的分佈式,就是個普通集羣。由於這致使你要麼消費者每次隨機鏈接一個實例而後拉取數據,要麼固定鏈接那個 queue 所在實 例消費數據,前者有數據拉取的開銷,後者致使單實例性能瓶頸。並且若是那個放 queue 的實例宕機了,會致使接下來其餘實例就沒法從那個實例拉取,若是你開啓了消息持久化,讓 RabbitMQ 落地存儲消息的話,消息不必定會丟,得等這個實例恢復了,而後才能夠繼續從這個 queue 拉取數據。
鏡像集羣模式的策略是高可用策略,指定的時候能夠要求數據同步到全部節點的,也能夠要求同步到指定數量的節點,再次建立 queue 的時候,應用這個策略,就會自動將數據同步到其餘的 節點上去了。api
https://www.javazhiyin.com/22905.html緩存
五、如何解決消息隊列的延時以及過時失效問題?
其實本質針對的場景,都是說,可能你的消費端出了問題,不消費了;或者消費的速度極其慢,形成消息堆積了,MQ存儲快要爆了,甚至開始過時失效刪除數據了。異步
針對這個問題能夠有事前、事中、過後三種處理
六、RabbitMQ如何保證不丟數據?
須要考慮3個可能丟數據的地方:生產端、隊列自己、消費端
設置持久化有兩個步驟:
七、如何保證隊列的消息不被重複消費?
這個須要靈活做答,考察的是思考力,由於消費的場景有不少,有數據庫、有緩存、有第三方接口
八、集羣節點類型都有什麼?
節點的存儲類型分爲兩種:
磁盤節點就是配置信息和元信息存儲在磁盤上,內存節點把這些信息存儲在內存中,固然內次節點的性能是大大超越磁盤節點的。單節點系統必須是磁盤節點,不然每次你重啓RabbitMQ以後全部的系統配置信息都會丟失。RabbitMQ要求集羣中至少有一個磁盤節點,當節點加入和離開集羣時,必須通知磁盤節點。