消息隊列MQ面試專題(rabbitmq)

正文:

1、什么是 rabbitmq

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

2、為什么要使用 rabbitmq

在分布式系統(tǒng)下具備異步,削峰,負載均衡等一系列高級功能;

擁有持久化的機制,進程消息,隊列中的信息也可以保存下來。

實現(xiàn)消費者和生產(chǎn)者之間的解耦。

對于高并發(fā)場景下,利用消息隊列可以使得同步訪問變?yōu)榇性L問達到一定量的限流,利于數(shù)據(jù)庫的操作。

可以使用消息隊列達到異步下單的效果,排隊中,后臺進行邏輯下單。

3、使用 rabbitmq 的場景

服務(wù)間異步通信

順序消費

定時任務(wù)

請求削峰

4、如何確保消息正確地發(fā)送至 RabbitMQ?如何確保消息接收方消費了消息?

發(fā)送方確認模式

將信道設(shè)置成 con?rm 模式(發(fā)送方確認模式),則所有在信道上發(fā)布的消息都會被指派一個唯一的 ID。

一旦消息被投遞到目的隊列后,或者消息被寫入磁盤后(可持久化的消息),信道會發(fā)送一個確認給生產(chǎn)者(包含消息唯一 ID)。

如果 RabbitMQ 發(fā)生內(nèi)部錯誤從而導(dǎo)致消息丟失,會發(fā)送一條 nack(notacknowledged,未確認)消息。發(fā)送方確認模式是異步的,生產(chǎn)者應(yīng)用程序在等待確認的同時,可以繼續(xù)發(fā)送消息。當確認消息到達生產(chǎn)者應(yīng)用程序,生產(chǎn)者應(yīng)用程序的回調(diào)方法就會被觸發(fā)來處理確認消息。

接收方確認機制

接收方消息確認機制

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

下面羅列幾種特殊情況

如果消費者接收到消息,在確認之前斷開了連接或取消訂閱,RabbitMQ 會認為消息沒有被分發(fā),然后重新分發(fā)給下一個訂閱的消費者。

(可能存在消息重復(fù)消費的隱患,需要去重)如果消費者接收到消息卻沒有確認消息,連接也未斷開,則 RabbitMQ 認為該消費者繁忙,將不會給該消費者分發(fā)更多的消息。

5、如何避免消息重復(fù)投遞或重復(fù)消費?

在消息生產(chǎn)時,MQ 內(nèi)部針對每條生產(chǎn)者發(fā)送的消息生成一個 inner-msg-id,作為去重的依據(jù)(消息投遞失敗并重傳),避免重復(fù)的消息進入隊列;

在消息消費時,要求消息體中必須要有一個 bizId(對于同一業(yè)務(wù)全局唯一,如支付 ID、訂單 ID、帖子 ID 等)作為去重的依據(jù),避免同一條消息被重復(fù)消費。

6、消息基于什么傳輸?

由于 TCP 連接的創(chuàng)建和銷毀開銷較大,且并發(fā)數(shù)受系統(tǒng)資源限制,會造成性能瓶頸。RabbitMQ 使用信道的方式來傳輸數(shù)據(jù)。信道是建立在真實的 TCP 連接內(nèi)的虛擬連接,且每條 TCP 連接上的信道數(shù)量沒有限制

7、消息如何分發(fā)?

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

通過路由可實現(xiàn)多消費的功能

8、消息怎么路由?

消息提供方->路由->一至多個隊列

消息發(fā)布到交換器時,消息將擁有一個路由鍵(routing key),在消息創(chuàng)建時設(shè)定。

通過隊列路由鍵,可以把隊列綁定到交換器上。

消息到達交換器后,RabbitMQ 會將消息的路由鍵與隊列的路由鍵進行匹配(針對不同的交換器有不同的路由規(guī)則);

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

fanout:如果交換器收到消息,將會廣播到所有綁定的隊列上

direct:如果路由鍵完全匹配,消息就被投遞到相應(yīng)的隊列

topic:可以使來自不同源頭的消息能夠到達同一個隊列。使用 topic 交換器時,可以使用通配符

9、如何確保消息不丟失?

消息持久化,當然前提是隊列必須持久化

RabbitMQ 確保持久性消息能從服務(wù)器重啟中恢復(fù)的方式是,將它們寫入磁盤上的一個持久化日志文件,當發(fā)布一條持久性消息到持久交換器上時,Rabbit 會在消息提交到日志文件后才發(fā)送響應(yīng)。

一旦消費者從持久隊列中消費了一條持久化消息,RabbitMQ 會在持久化日志中把這條消息標記為等待垃圾收集。如果持久化消息在被消費之前 RabbitMQ 重啟,那么 Rabbit 會自動重建交換器和隊列(以及綁定),并重新發(fā)布持久化日志文件中的消息到合適的隊列。

10、使用 RabbitMQ 有什么好處?

服務(wù)間高度解耦

異步通信性能高

流量削峰

11、RabbitMQ 的集群

鏡像集群模式

你創(chuàng)建的 queue,無論元數(shù)據(jù)還是 queue 里的消息都會存在于多個實例上,然后每次你寫消息到 queue 的時候,都會自動把消息到多個實例的 queue 里進行消息同步。

好處在于,你任何一個機器宕機了,沒事兒,別的機器都可以用。壞處在于,第一,這個性能開銷也太大了吧,消息同步所有機器,導(dǎo)致網(wǎng)絡(luò)帶寬壓力和消耗很重!第二,這么玩兒,就沒有擴展性可言了,如果某個 queue 負載很重,你加機器,新增的機器也包含了這個 queue 的所有數(shù)據(jù),并沒有辦法線性擴展你的 queue

12、mq 的缺點

系統(tǒng)可用性降低

系統(tǒng)引入的外部依賴越多,越容易掛掉,本來你就是 A 系統(tǒng)調(diào)用 BCD 三個系統(tǒng)的接口就好了,人 ABCD 四個系統(tǒng)好好的,沒啥問題,你偏加個 MQ 進來,萬一MQ 掛了咋整?MQ 掛了,整套系統(tǒng)崩潰了,你不就完了么。

系統(tǒng)復(fù)雜性提高

硬生生加個 MQ 進來,你怎么保證消息沒有重復(fù)消費?怎么處理消息丟失的情況?怎么保證消息傳遞的順序性?頭大頭大,問題一大堆,痛苦不已

一致性問題A 系統(tǒng)處理完了直接返回成功了,人都以為你這個請求就成功了;但是問題是,要是 BCD 三個系統(tǒng)那里,BD 兩個系統(tǒng)寫庫成功了,結(jié)果 C 系統(tǒng)寫庫失敗了,咋整?你這數(shù)據(jù)就不一致了。

所以消息隊列實際是一種非常復(fù)雜的架構(gòu),你引入它有很多好處,但是也得針對它帶來的壞處做各種額外的技術(shù)方案和架構(gòu)來規(guī)避掉,最好之后,你會發(fā)現(xiàn),媽呀,系統(tǒng)復(fù)雜度提升了一個數(shù)量級,也許是復(fù)雜了 10 倍。但是關(guān)鍵時刻,用,還是得用的

13、Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么區(qū)別?

對于吞吐量來說kafka和RocketMQ支撐高吞吐,ActiveMQ和RabbitMQ比他們低一個數(shù)量級。對于延遲量來說RabbitMQ是最低的。

從社區(qū)活躍度

按照目前網(wǎng)絡(luò)上的資料,RabbitMQ 、activeM 、ZeroMQ 三者中,綜合來看,RabbitMQ 是首選。

持久化消息比較

ActiveMq 和RabbitMq 都支持。持久化消息主要是指我們機器在不可抗力因素等情況下掛掉了,消息不會丟失的機制。

綜合技術(shù)實現(xiàn)

可靠性、靈活的路由、集群、事務(wù)、高可用的隊列、消息排序、問題追蹤、可視化管理工具、插件系統(tǒng)等等。

RabbitMq / Kafka 最好,ActiveMq 次之,ZeroMq 最差。當然ZeroMq 也可以做到,不過自己必須手動寫代碼實現(xiàn),代碼量不小。尤其是可靠性中的:持久性、投遞確認、發(fā)布者證實和高可用性。

高并發(fā)

毋庸置疑,RabbitMQ 最高,原因是它的實現(xiàn)語言是天生具備高并發(fā)高可用的erlang 語言。

比較關(guān)注的比較, RabbitMQ 和 Kafka

RabbitMq 比Kafka 成熟,在可用性上,穩(wěn)定性上,可靠性上, RabbitMq 勝于 Kafka (理論上)。另外,Kafka 的定位主要在日志等方 面, 因為Kafka 設(shè)計的初衷就是處理日志的,可以看做是一個日志(消息)系統(tǒng)一個重要組件,針對性很強,所以 如果業(yè)務(wù)方面還是建議選擇 RabbitMq 。還有就是,Kafka 的性能(吞吐量、TPS )比RabbitMq 要高出來很多

14、如何保證高可用的?

RabbitMQ 是比較有代表性的,因為是基于主從(非分布式)做高可用性的,我們就以 RabbitMQ 為例子講解第一種 MQ 的高可用性怎么實現(xiàn)。RabbitMQ 有三種模式:單機模式、普通集群模式、鏡像集群模式。

單機模式,就是 Demo 級別的,一般就是你本地啟動了玩玩兒的?,沒人生產(chǎn)用單機模式普通集群模式,意思就是在多臺機器上啟動多個

RabbitMQ 實例,每個機器啟動一個。你創(chuàng)建的queue,只會放在一個 RabbitMQ 實例上,但是每個實例都同步 queue 的元數(shù)據(jù)(元數(shù)據(jù)可以認為是queue 的一些配置信息,通過元數(shù)據(jù),可以找到 queue 所在實例)。你消費的時候,實際上如果連接到了另外一個實例,那么那個實例會從 queue 所在實例上拉取數(shù)據(jù)過來。這方案主要是提高吞吐量的,就是說讓集群中多個節(jié)點來服務(wù)某個 queue 的讀寫操作。

鏡像集群模式:這種模式,才是所謂的 RabbitMQ 的高可用模式。跟普通集群模式不一樣的是,在鏡像集群模式下,你創(chuàng)建的 queue,無論元數(shù)據(jù)還是 queue 里的消息都會存在于多個實例上,就是說,每個 RabbitMQ 節(jié)點都有這個 queue 的一個完整鏡像,包含 queue 的全部數(shù)據(jù)的意思。然后每次你寫消息到 queue 的時候,都會自動把消息同步到多個實例的 queue 上。RabbitMQ 有很好的管理控制臺,就是在后臺新增一個策略,這個策略是鏡像集群模式的策略,指定的時候是可以要求數(shù)據(jù)同步到所有節(jié)點的,也可以要求同步到指定數(shù)量的節(jié)點,再次創(chuàng)建 queue 的時候,應(yīng)用這個策略,就會自動將數(shù)據(jù)同步到其他的節(jié)點上去了。這樣的話,好處在于,你任何一個機器宕機了,沒事兒,其它機器(節(jié)點)還包含了這個 queue 的完整數(shù)據(jù),別的 consumer 都可以到其它節(jié)點上去消費數(shù)據(jù)。壞處在于,第一,這個性能開銷也太大了吧,消息需要同步到所有機器上,導(dǎo)致網(wǎng)絡(luò)帶寬壓力和消耗很重!RabbitMQ 一個 queue 的數(shù)據(jù)都是放在一個節(jié)點里的,鏡像集群下,也是每個節(jié)點都放這個 queue 的完整數(shù)據(jù)

Kafka 一個最基本的架構(gòu)認識:由多個 broker 組成,每個 broker 是一個節(jié)點;你創(chuàng)建一個 topic,這個 topic 可以劃分為多個 partition, 每個 partition 可以存在于不同的 broker 上,每個 partition 就放一部分數(shù)據(jù)。這就是天然的分布式消息隊列,就是說一個 topic 的數(shù)據(jù), 是分散放在多個機器上的,每個機器就放一部分數(shù)據(jù)。Kafka 0.8 以后,提供了 HA 機制,就是 replica(復(fù)制品) 副本機制。每個partition 的數(shù)據(jù)都會同步到其它機器上,形成自己的多個 replica 副本。所有 replica 會選舉一個leader 出來,那么生產(chǎn)和消費都跟這個 leader 打交道,然后其他 replica 就是 follower。寫的時候,leader 會負責把數(shù)據(jù)同步到所有 follower 上去,讀的時候就直接讀 leader 上的數(shù)據(jù)即

可。只能讀寫leader?很簡單,要是你可以隨意讀寫每個 follower,那么就要 care 數(shù)據(jù)一致性的問題,系統(tǒng)復(fù)雜度太高,很容易出問題。

Kafka 會均勻地將一個 partition 的所有 replica 分布在不同的機器上,這樣才可以提高容錯性。因為如果某個 broker 宕機了,沒事兒,那個 broker上面的 partition 在其他機器上都

有副本的,如果這上面有某個 partition 的 leader,那么此時會從 follower 中重新選舉一個新的 leader出來,大家繼續(xù)讀寫那個新的leader 即可。這就有所謂的高可用性了。寫數(shù)據(jù)的時候,生產(chǎn)者就寫leader,然后 leader 將數(shù)據(jù)落地寫本地磁盤,接著其他 follower 自己主動從 leader 來 pull 數(shù)據(jù)。一旦所有 follower 同步好數(shù)據(jù)了,就會發(fā)送 ack 給 leader,leader 收到所有 follower 的 ack 之后,就會返回寫成功的消息給生產(chǎn)者。(當然,這只是其中一種模式,還可以適當調(diào)整這個行為)消費的時候,只會從 leader 去讀,但是只有當一個消息已經(jīng)被所有 follower 都同步成功返回 ack 的時候,這個消息才會被消費者讀到

15、如何保證消息的可靠傳輸?如果消息丟了怎么辦

數(shù)據(jù)的丟失問題,可能出現(xiàn)在生產(chǎn)者、MQ、消費者中

生產(chǎn)者丟失:生產(chǎn)者將數(shù)據(jù)發(fā)送到 RabbitMQ 的時候,可能數(shù)據(jù)就在半路給搞丟了,因為網(wǎng)絡(luò)問題啥的,都有可能。此時可以選擇用RabbitMQ 提供的事務(wù)功能,就是生產(chǎn)者發(fā)送數(shù)據(jù)之前開啟 RabbitMQ事務(wù)channel.txSelect,然后發(fā)送消息,如果消息沒有成功被RabbitMQ 接收到,那么生產(chǎn)者會收到異常報錯,此時就可以回滾事務(wù)channel.txRollback,然后重試發(fā)送消息;如果收到了消息,那么可以提交事務(wù)channel.txCommit。吞吐量會下來,因為太耗性能。所以一般來說,如果你要確保說寫RabbitMQ 的消息別丟,可以開啟con?rm模式,在生產(chǎn)者那里設(shè)置開啟con?rm模式之后,你每次寫的消息都會分配一個唯一的 id,然后如果寫入了 RabbitMQ 中,

RabbitMQ 會給你回傳一個ack消息,告訴你說這個消息 ok 了。如果 RabbitMQ 沒能處理這個消息,會回調(diào)你一個nack接口,告訴你這個消息接收失敗,你可以重試。而且你可以結(jié)合這個機制自己在內(nèi)存里維護每個消息 id 的狀態(tài),如果超過一定時間還沒接收到這個消息的回調(diào),那么你可以重發(fā)。事務(wù)機制和cno?rm機制最大的不同在于,事務(wù)機制是同步的,你提交一個事務(wù)之后會阻塞在那兒,但是con?rm機 制是異步的,你發(fā)送個消息之后就可以發(fā)送下一個消息,然后那個消息RabbitMQ 接收了之后會異步回調(diào)你一個接口通知你這個消息接收到了。所以一般在生產(chǎn)者這塊避免數(shù)據(jù)丟失,都是用con?rm機制的

MQ中丟失:就是 RabbitMQ 自己弄丟了數(shù)據(jù),這個你必須開啟 RabbitMQ 的持久化,就是消息寫入之后會持久化到磁盤,哪怕是

RabbitMQ 自己掛了,恢復(fù)之后會自動讀取之前存儲的數(shù)據(jù),一般數(shù)據(jù)不會丟。設(shè)置持久化有兩個步驟:創(chuàng)建 queue 的時候?qū)⑵湓O(shè)置為持久化,這樣就可以保證 RabbitMQ 持久化 queue 的元數(shù)據(jù),但是不會持久化 queue 里的數(shù)據(jù)。第二個是發(fā)送消息的時候?qū)⑾⒌膁eliveryMode 設(shè)置為 2,就是將消息設(shè)置為持久化的,此時 RabbitMQ 就會將消息持久化到磁盤上去。必須要同時設(shè)置這兩個持久化才

行,RabbitMQ 哪怕是掛了,再次重啟,也會從磁盤上重啟恢復(fù)queue,恢復(fù)這個 queue 里的數(shù)據(jù)。持久化可以跟生產(chǎn)者那邊的con?rm機制配合起來,只有消息被持久化到磁盤之后,才會通知生產(chǎn)者ack了,所以哪怕是在持久化到磁盤之前,RabbitMQ 掛了,數(shù)據(jù)丟了,生產(chǎn)者收不到ack,你也是可以自己重發(fā)的。注意,哪怕是你給 RabbitMQ 開啟了持久化機制,也有一種可能,就是這個消息寫到了 RabbitMQ 中,但是還沒來得及持久化到磁盤上,結(jié)果不巧,此時RabbitMQ 掛了,就會導(dǎo)致內(nèi)存里的一點點數(shù)據(jù)丟失

消費端丟失:你消費的時候,剛消費到,還沒處理,結(jié)果進程掛了,比如重啟了,那么就尷尬了,RabbitMQ 認為你都消費了,這數(shù)據(jù)就丟了。這個時候得用 RabbitMQ 提供的ack機制,簡單來說,就是你關(guān)閉 RabbitMQ 的自動ack,可以通過一個 api 來調(diào)用就行,然后每次你自己代碼里確保處理完的時候,再在程序里ack一把。這樣的話,如果你還沒處理完,不就沒有ack?那 RabbitMQ 就認為你還沒處理完, 這個時候 RabbitMQ 會把這個消費分配給別的 consumer 去處理,消息是不會丟的

16、如何保證消息的順序性

先看看順序會錯亂的場景:RabbitMQ:一個 queue,多個 consumer,這不明顯亂了;

解決:

17、如何解決消息隊列的延時以及過期失效問題?消息隊列滿了以后該怎么處理?有幾百萬 消息持續(xù)積壓幾小時,說說怎么解決

消息積壓處理辦法:臨時緊急擴容:

先修復(fù) consumer 的問題,確保其恢復(fù)消費速度,然后將現(xiàn)有 cnosumer 都停掉。新建一個 topic,partition 是原來的 10 倍,臨時建立好原先 10 倍的 queue 數(shù)量。然后寫一個臨時的分發(fā)數(shù)據(jù)的 consumer 程序,這個程序部署上去消費積壓的數(shù)據(jù),消費之后不做耗時的處理,直接均勻輪詢寫入臨時建立好的 10 倍數(shù)量的 queue。

接著臨時征用 10 倍的機器來部署 consumer,每一批 consumer 消費一個臨時 queue 的數(shù)據(jù)。這種做法相當于是臨時將 queue 資源和consumer 資源擴大 10 倍,以正常的 10 倍速度來消費數(shù)據(jù)。等快速消費完積壓數(shù)據(jù)之后,得恢復(fù)原先部署的架構(gòu),重新用原先的consumer 機器來消費消息。MQ中消息失效:假設(shè)你用的是 RabbitMQ,RabbtiMQ 是可以設(shè)置過期時間的,也就是 TTL。如果消息在queue 中積壓超過一定的時間就會被 RabbitMQ 給清理掉,這個數(shù)據(jù)就沒了。那這就是第二個坑了。這就不是說數(shù)據(jù)會大量積壓在 mq里,而是大量的數(shù)據(jù)會直接搞丟。我們可以采取一個方案,就是批量重導(dǎo),這個我們之前線上也有類似的場景干過。就是大量積壓的時候, 我們當時就直接丟棄數(shù)據(jù)了,然后等過了高峰期以后,比如大家一起喝咖啡熬夜到晚上12點以后,用戶都睡覺了。這個時候我們就開始寫程序,將丟失的那批數(shù)據(jù),寫個臨時程序,一點一點的查出來,然后重新灌入 mq 里面去,把白天丟的數(shù)據(jù)給他補回來。也只能是這樣了。假設(shè) 1 萬個訂單積壓在 mq 里面,沒有處理,其中 1000個訂單都丟了,你只能手動寫程序把那 1000 個訂單給查出來,手動發(fā)到 mq 里去再補一次

mq消息隊列塊滿了:如果消息積壓在 mq 里,你很長時間都沒有處理掉,此時導(dǎo)致 mq 都快寫滿了,咋辦?這個還有別的辦法嗎?沒有, 誰讓你第一個方案執(zhí)行的太慢了,你臨時寫程序,接入數(shù)據(jù)來消費,消費一個丟棄一個,都不要了,快速消費掉所有的消息。然后走第二個方案,到了晚上再補數(shù)據(jù)吧

18、設(shè)計MQ的思路

比如說這個消息隊列系統(tǒng),我們從以下幾個角度來考慮一下:

首先這個 mq 得支持可伸縮性吧,就是需要的時候快速擴容,就可以增加吞吐量和容量,那怎么搞?設(shè)計個分布式的系統(tǒng)唄,參照一下kafka 的設(shè)計理念,broker -> topic -> partition,每個 partition 放一個機器,就存一部分數(shù)據(jù)。如果現(xiàn)在資源不夠了,簡單啊,給 topic增加 partition,然后做數(shù)據(jù)遷移,增加機器,不就可以存放更多數(shù)據(jù),提供更高的吞吐量了?

其次你得考慮一下這個 mq 的數(shù)據(jù)要不要落地磁盤吧?那肯定要了,落磁盤才能保證別進程掛了數(shù)據(jù)就丟了。那落磁盤的時候怎么落?。宽樞?qū)?,這樣就沒有磁盤隨機讀寫的尋址開銷,磁盤順序讀寫的性能是很高的,這就是 kafka 的思路。

其次你考慮一下你的 mq 的可用性???這個事兒,具體參考之前可用性那個環(huán)節(jié)講解的 kafka 的高可用保障機制。多副本 -> leader & follower -> broker 掛了重新選舉 leader 即可對外服務(wù)。能不能支持數(shù)據(jù) 0 丟失???可以的,參考我們之前說的那個 kafka 數(shù)據(jù)零丟失方案

19、什么是Message?

消息,消息是不具名的,它由消息頭和消息體組成。消息體是不透明的,而消息頭則由一系列的可選屬性組成,這些屬性包括 routing- key(路由鍵)、 priority(相對于其他消息的優(yōu)先權(quán))、 delivery-mode(指出該消息可能需要持久性存儲)等。

20、什么是Publisher ?

消息的生產(chǎn)者,也是一個向交換器發(fā)布消息的客戶端應(yīng)用程序。

21、什么是Exchange(將消息路由給隊列 )

交換器,用來接收生產(chǎn)者發(fā)送的消息并將這些消息路由給服務(wù)器中的隊列

22、什么是Binding(消息隊列和交換器之間的關(guān)聯(lián))

綁定,用于消息隊列和交換器之間的關(guān)聯(lián)。一個綁定就是基于路由鍵將交換器和消息隊列連接起來的路由規(guī)則,所以可以將交換器理解成一個由綁定構(gòu)成的路由表

23、什么是Queue?

消息隊列,用來保存消息直到發(fā)送給消費者。它是消息的容器,也是消息的終點。一個消息可投入一個或多個隊列。消息一直在隊列里面,等待消費者連接到這個隊列將其取走

24、什么是Connection ?

網(wǎng)絡(luò)連接,比如一個 TCP 連接。

25、什么是Channel?

信道, 多路復(fù)用連接中的一條獨立的雙向數(shù)據(jù)流通道。信道是建立在真實的 TCP 連接內(nèi)地虛擬連接, AMQP 命令都是通過信道發(fā)出去的, 不管是發(fā)布消息、訂閱隊列還是接收消息,這些動作都是通過信道完成。因為對于操作系統(tǒng)來說建立和銷毀 TCP 都是非常昂貴的開銷,所以引入了信道的概念,以復(fù)用一條 TCP 連接

26、什么是Consumer ?

消息的消費者,表示一個從消息隊列中取得消息的客戶端應(yīng)用程序

27、什么是Virtual Host ?

虛擬主機,表示一批交換器、消息隊列和相關(guān)對象。虛擬主機是共享相同的身份認證和加密環(huán)境的獨立服務(wù)器域。

28、什么是Broker?

表示消息隊列服務(wù)器實體

29、Exchange 類型 ?

Exchange 分發(fā)消息時根據(jù)類型的不同分發(fā)策略有區(qū)別, 目前共四種類型:direct、 fanout、topic、 headers 。headers 匹配 AMQP 消息的 header 而不是路由鍵,此外 headers 交換器和direct 交換器完全一致,但性能差很多,目前幾乎用不到了。

30、Direct 鍵(routing key)分布 ?

Direct:消息中的路由鍵(routing key)如果和 Binding 中的 binding key 一致,交換器就將消息發(fā)到對應(yīng)的隊列中。它是完全匹配、單播的模式。

31、Fanout(廣播分發(fā))?

Fanout:每個發(fā)到 fanout 類型交換器的消息都會分到所有綁定的隊列上去。很像子網(wǎng)廣播,每臺子網(wǎng)內(nèi)的主機都獲得了一份復(fù)制的消息。

fanout 類型轉(zhuǎn)發(fā)消息是最快的。

32、topic 交換器(模式匹配) ?

topic 交換器:topic 交換器通過模式匹配分配消息的路由鍵屬性,將路由鍵和某個模式進行匹配,此時隊列需要綁定到一個模式上。它將路由鍵和綁定鍵的字符串切分成單詞,這些單詞之間用點隔開。它同樣也會識別兩個通配符:符號“#” 和符號“” 。#匹配 0 個或多個單詞, 匹配不多不少一個單詞。

我這有全套大廠面試題需要的轉(zhuǎn)發(fā)+關(guān)注 私信我“666”

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容