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

公衆號:狸貓技術窩

做者:愛釣魚的桌子哥,資深架構師面試

目錄

1.有Broker的暴力路由:Kafka 數據庫

2.有Broker的複雜路由:RabbitMQ 服務器

3.無Broker的通訊流派:ZeroMQ 網絡

4.總結架構

寫在前面

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

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

上述拋出的問題,一樣在很多公司的Java工程師面試中出現,特別是當你簡歷上的技術棧包含了這些技術,面試官每每喜歡用這個問題,對你進行摸底考察。post

本文咱們就一塊兒來探討一下。性能

(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來消費。以下圖所示:

若是要實現Publish/Subscribe的模型呢?就是說生產者發送的每條消息,都要讓全部消費都消費到,怎麼實現?

那就讓每一個消費者都是一個獨立的消費組,這樣每條消息都會發送給全部的消費組,每一個消費組裏那惟一的一個消費者必定會消費到全部的消息。

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

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

因此Kafka天生適合的場景,就是大數據領域的實時數據計算的場景。

由於在大數據的場景下,一般是弱業務的場景,沒有太多複雜的業務系統交互,而主要是大量的數據流入Kafka,而後進行實時計算。

因此就是須要簡單的消費模型,可是必須在內核中對吞吐量和性能進行大幅度的優化。

所以Kafka技術一般是在大數據的實時數據計算領域中使用的,好比說每秒處理幾十萬條消息,甚至每秒處理上百萬條消息。


(2)有Broker的複雜路由

第二個流派,就是RabbitMQ爲表明的流派,他強調的不是說如何提高性能和吞吐量,關注的是說要提供很是強大、複雜並且完善的消息路由功能。


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


在RabbitMQ中引入了一個很是核心的概念,叫作Exchange,這個Exchange就是負責根據複雜的業務規則把消息路由到內部的不一樣的Queue裏去。


舉個例子,若是要實現最簡單的隊列功能,就是讓exchange往一個queue裏寫數據,而後多個消費者來消費這個queue裏的數據,每條消息只能給一個消費者,那麼能夠是相似下面的方式。


若是想要實現Pub/Sub的模型,就是一條消息要被全部的消費者給消費到,那麼就可讓每一個消費者都有一個本身的Queue,而後綁定到一個Exchange上去。

接着,這個Exchange就設定把消息路由給全部的Queue便可,以下面這樣。

此時Exchange能夠把每條消息都路由給全部的Queue,每一個Consumer均可以從本身的Queue裏拿到全部的消息。



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做爲分佈式系統之間的消息通訊,以下面那樣。


(4)總結

其實如今基本上MQ主要就是這三個流派,不少小衆的MQ通常不多有人會用。

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

  1. 業務系統之間異步通訊

  2. 大數據領域的實時數據計算

因此通常業務系統之間通訊就是會採用RabbitMQ/RocketMQ,須要複雜的消息路由功能的支撐。

大數據的實時計算場景會採用Kafka,須要簡單的消費模型,可是超高的吞吐量。

至於ZeroMQ,通常來講,少數分佈式系統中子系統之間的分佈式通訊時會採用,做爲輕量級的異步化的通訊組件。

END


做者簡介:

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

做者前後工做於滴滴、百度、字節跳動等國內一線互聯網大廠,從事基礎架構相關工做。帶領團隊設計與構建了大規模的分佈式存儲系統、分佈式消息中間件、分佈式數據庫,對分佈式架構設計、系統高可用體系構建、基礎中間件架構都有豐富的經驗。


END

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

做者:狸貓技術窩 連接:https://juejin.im/post/5ce1975af265da1bd42450b5 來源:掘金 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
相關文章
相關標籤/搜索