熟練掌握各種MQ?那面試官很可能用這道題目先摸摸你的老底!

狸貓技術窩發表於2019-05-29
公眾號:狸貓技術窩

作者:愛釣魚的桌子哥,資深架構師

目錄

1.有Broker的暴力路由:Kafka

2.有Broker的複雜路由:RabbitMQ

3.無Broker的通訊流派:ZeroMQ

4.總結

寫在前面

我們知道,目前市面上的MQ包括Kafka、RabbitMQ、ZeroMQ、RocketMQ等等。

那麼他們之間究竟有什麼本質區別,分別適用於什麼場景呢?

上述丟擲的問題,同樣在不少公司的Java工程師面試中出現,特別是當你簡歷上的技術棧包含了這些技術,面試官往往喜歡用這個問題,對你進行摸底考察。

本文我們就一起來探討一下。

(1)有Broker的暴力路由

這個流派最典型的就是Kafka,Kafka實際上為了提升效能,簡化了MQ功能模型,僅僅提供了一些最基礎的MQ相關的功能,但是大幅度優化和提升了吞吐量。

首先,這個流派一定是有一個Broker角色的,也就是說,Kafka需要部署一套伺服器叢集,每臺機器上都有一個Kafka Broker程式,這個程式就負責接收請求,儲存資料,傳送資料。

Kafka的生產消費模型做的相對是比較暴力簡單的,就是簡單的資料流模型。

簡單來說,他有一個概念,叫做“Topic”,你可以往這個“Topic”裡寫資料,然後讓別人從這裡來消費。

這個Topic可以劃分為多個Partition,每個Partition放一臺機器上,儲存一部分資料。

在寫訊息到Topic的時候,會自動把你這個訊息給分發到某一個Partition上去。

然後消費訊息的時候,有一個Consumer Group的概念,你部署在多臺機器上的Consumer可以組成一個Group,一個Partition只能給一個Consumer消費,一個Cosumer可以消費多個Partition,這是最最核心的一點。

通過這個模型,保證一個Topic裡的每條訊息,只會交給Consumer Group裡的一個Consumer來消費,形成了一個Queue(佇列)的效果。

假如你想要有一個Queue的效果,也就是希望不停的往Queue裡寫資料,然後多個消費者消費,每條訊息就只能給一個消費者,那麼通過Kafka來實現,其實就是生產者寫多個Partition,每個Partition只能給Consumer Group中的一個Consumer來消費。如下圖所示:

熟練掌握各種MQ?那面試官很可能用這道題目先摸摸你的老底!

如果要實現Publish/Subscribe的模型呢?就是說生產者傳送的每條訊息,都要讓所有消費都消費到,怎麼實現?

那就讓每個消費者都是一個獨立的消費組,這樣每條訊息都會傳送給所有的消費組,每個消費組裡那唯一的一個消費者一定會消費到所有的訊息。

熟練掌握各種MQ?那面試官很可能用這道題目先摸摸你的老底!

但是除此之外,Kafka就沒有任何其他的消費功能了,就是如此簡單,所以屬於一種比較暴力直接的流派。

它就是簡單的消費模型,實現最基礎的Queue和Pub/Sub兩種消費模型,但是核心中大幅度優化和提升了效能以及吞吐量。

所以Kafka天生適合的場景,就是大資料領域的實時資料計算的場景。

因為在大資料的場景下,通常是弱業務的場景,沒有太多複雜的業務系統互動,而主要是大量的資料流入Kafka,然後進行實時計算。

所以就是需要簡單的消費模型,但是必須在核心中對吞吐量和效能進行大幅度的優化。

因此Kafka技術通常是在大資料的實時資料計算領域中使用的,比如說每秒處理幾十萬條訊息,甚至每秒處理上百萬條訊息。


(2)有Broker的複雜路由

第二個流派,就是RabbitMQ為代表的流派,他強調的不是說如何提升效能和吞吐量,關注的是說要提供非常強大、複雜而且完善的訊息路由功能。


所以對於RabbitMQ而言,他就不是那麼簡單的Topic-Partition的消費模型了。


在RabbitMQ中引入了一個非常核心的概念,叫做Exchange,這個Exchange就是負責根據複雜的業務規則把訊息路由到內部的不同的Queue裡去。


舉個例子,如果要實現最簡單的佇列功能,就是讓exchange往一個queue裡寫資料,然後多個消費者來消費這個queue裡的資料,每條訊息只能給一個消費者,那麼可以是類似下面的方式。

熟練掌握各種MQ?那面試官很可能用這道題目先摸摸你的老底!


如果想要實現Pub/Sub的模型,就是一條訊息要被所有的消費者給消費到,那麼就可以讓每個消費者都有一個自己的Queue,然後繫結到一個Exchange上去。

接著,這個Exchange就設定把訊息路由給所有的Queue即可,如下面這樣。

此時Exchange可以把每條訊息都路由給所有的Queue,每個Consumer都可以從自己的Queue裡拿到所有的訊息。


熟練掌握各種MQ?那面試官很可能用這道題目先摸摸你的老底!


RabbitMQ這種流派,其實最核心的是,基於Exchange這個概念,他可以做很多複雜的事情。

比如:如果你想要某個Consumer只能消費到某一類資料,那麼Exchange可以把訊息裡比如帶“XXX”字首的訊息路由給某個Queue。或者你可以限定某個Consumer就只能消費某一部分資料。總之在這裡你可以做很多的限制,設定複雜的路由規則。

但是也正是因為引入了這種複雜的消費模型,支援複雜的路由功能,導致RabbitMQ在核心以及架構設計上沒法像Kafka做的那麼的輕量級、高效能、可擴充套件、高吞吐,所以RabbitMQ在吞吐量上要比Kafka低一個數量級。

所以這種流派的MQ,往往適合用在Java業務系統中,不同的業務系統需要進行復雜的訊息路由。

比如說業務系統A傳送了10條訊息,其中3條訊息是給業務系統B的,7條訊息是給業務系統C的,要實現這種複雜的路由模型,就必須依靠RabbitMQ來實現。

當然,對於這種業務系統之間的訊息流轉而言,可能不需要那麼高的吞吐量,可能每秒業務系統之間也就轉發幾十條或者幾百條訊息,那麼就完全適合採用RabbitMQ來實現。


(3)無Broker的通訊流派

ZeroMQ代表的是第三種MQ。說白了,他是不需要在伺服器上部署的,就是一個客戶端的庫而已。

也就是說,他主要是封裝了底層的Socket網路通訊,然後一個系統要傳送一條訊息給另外一個訊息消費 。

通過ZeroMQ,本質就是底層ZeroMQ傳送一條訊息到另外一個系統上去。

所以ZeroMQ是去中心化的,不需要跟Kafka、RabbitMQ一樣在伺服器上部署的。

他主要是用來進行業務系統之間的網路通訊的,有點類似於比如你是一個分散式系統架構,那麼此時分散式架構中的各個子系統互相之間要通訊,你是基於Dubbo RPC?還是Spring Cloud HTTP?

可能上述兩種你都不想要,就是要基於原始的Socket進行網路通訊,簡單的收發訊息而已。

此時就可以使用ZeroMQ作為分散式系統之間的訊息通訊,如下面那樣。

熟練掌握各種MQ?那面試官很可能用這道題目先摸摸你的老底!


(4)總結

其實現在基本上MQ主要就是這三個流派,很多小眾的MQ一般很少有人會用。

而且用MQ的場景主要就是兩大類:

  1. 業務系統之間非同步通訊

  2. 大資料領域的實時資料計算

所以一般業務系統之間通訊就是會採用RabbitMQ/RocketMQ,需要複雜的訊息路由功能的支撐。

大資料的實時計算場景會採用Kafka,需要簡單的消費模型,但是超高的吞吐量。

至於ZeroMQ,一般來說,少數分散式系統中子系統之間的分散式通訊時會採用,作為輕量級的非同步化的通訊元件。

END


作者簡介:

愛釣魚的桌子哥,資深架構師

作者先後工作於滴滴、百度、位元組跳動等國內一線網際網路大廠,從事基礎架構相關工作。帶領團隊設計與構建了大規模的分散式儲存系統、分散式訊息中介軟體、分散式資料庫,對分散式架構設計、系統高可用體系構建、基礎中介軟體架構都有豐富的經驗。


END

長按下圖二維碼,即刻關注【狸貓技術窩】 阿里、京東、美團、位元組跳動 頂尖技術專家坐鎮 為IT人打造一個 “有溫度” 的技術窩!

熟練掌握各種MQ?那面試官很可能用這道題目先摸摸你的老底!

作者:狸貓技術窩
連結:https://juejin.im/post/5ce1975af265da1bd42450b5
來源:掘金
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。


相關文章