1. 程式人生 > >為什麼使用訊息佇列?訊息佇列有什麼優點和缺點?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什麼優點和缺點?

為什麼使用訊息佇列?訊息佇列有什麼優點和缺點?Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什麼優點和缺點?

面試題

  • 為什麼使用訊息佇列?
  • 訊息佇列有什麼優點和缺點?
  • Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什麼區別,以及適合哪些場景?

面試官心理分析

其實面試官主要是想看看:

  • 第一,你知不知道你們系統裡為什麼要用訊息佇列這個東西?

    不少候選人,說自己專案裡用了 Redis、MQ,但是其實他並不知道自己為什麼要用這個東西。其實說白了,就是為了用而用,或者是別人設計的架構,他從頭到尾都沒思考過。

    沒有對自己的架構問過為什麼的人,一定是平時沒有思考的人,面試官對這類候選人印象通常很不好。因為面試官擔心你進了團隊之後只會木頭木腦的幹呆活兒,不會自己思考。

  • 第二,你既然用了訊息佇列這個東西,你知不知道用了有什麼好處&壞處?

    你要是沒考慮過這個,那你盲目弄個 MQ 進系統裡,後面出了問題你是不是就自己溜了給公司留坑?你要是沒考慮過引入一個技術可能存在的弊端和風險,面試官把這類候選人招進來了,基本可能就是挖坑型選手。就怕你幹 1 年挖一堆坑,自己跳槽了,給公司留下無窮後患。

  • 第三,既然你用了 MQ,可能是某一種 MQ,那麼你當時做沒做過調研?

    你別傻乎乎的自己拍腦袋看個人喜好就瞎用了一個 MQ,比如 Kafka,甚至都從沒調研過業界流行的 MQ 到底有哪幾種。每一個 MQ 的優點和缺點是什麼。每一個 MQ 沒有絕對的好壞,但是就是看用在哪個場景可以揚長避短,利用其優勢,規避其劣勢。

    如果是一個不考慮技術選型的候選人招進了團隊,leader 交給他一個任務,去設計個什麼系統,他在裡面用一些技術,可能都沒考慮過選型,最後選的技術可能並不一定合適,一樣是留坑。

面試題剖析

為什麼使用訊息佇列

其實就是問問你訊息佇列都有哪些使用場景,然後你專案裡具體是什麼場景,說說你在這個場景裡用訊息佇列是什麼?

面試官問你這個問題,期望的一個回答是說,你們公司有個什麼業務場景,這個業務場景有個什麼技術挑戰,如果不用 MQ 可能會很麻煩,但是你現在用了 MQ 之後帶給了你很多的好處。

先說一下訊息佇列常見的使用場景吧,其實場景有很多,但是比較核心的有 3 個:解耦、非同步、削峰。

解耦

看這麼個場景。A 系統傳送資料到 BCD 三個系統,通過介面呼叫傳送。如果 E 系統也要這個資料呢?那如果 C 系統現在不需要了呢?A 系統負責人幾乎崩潰......

在這個場景中,A 系統跟其它各種亂七八糟的系統嚴重耦合,A 系統產生一條比較關鍵的資料,很多系統都需要 A 系統將這個資料傳送過來。A 系統要時時刻刻考慮 BCDE 四個系統如果掛了該咋辦?要不要重發,要不要把訊息存起來?頭髮都白了啊!

如果使用 MQ,A 系統產生一條資料,傳送到 MQ 裡面去,哪個系統需要資料自己去 MQ 裡面消費。如果新系統需要資料,直接從 MQ 裡消費即可;如果某個系統不需要這條資料了,就取消對 MQ 訊息的消費即可。這樣下來,A 系統壓根兒不需要去考慮要給誰傳送資料,不需要維護這個程式碼,也不需要考慮人家是否呼叫成功、失敗超時等情況。

總結:通過一個 MQ,Pub/Sub 釋出訂閱訊息這麼一個模型,A 系統就跟其它系統徹底解耦了。

面試技巧:你需要去考慮一下你負責的系統中是否有類似的場景,就是一個系統或者一個模組,呼叫了多個系統或者模組,互相之間的呼叫很複雜,維護起來很麻煩。但是其實這個呼叫是不需要直接同步呼叫介面的,如果用 MQ 給它非同步化解耦,也是可以的,你就需要去考慮在你的專案裡,是不是可以運用這個 MQ 去進行系統的解耦。在簡歷中體現出來這塊東西,用 MQ 作解耦。

非同步

再來看一個場景,A 系統接收一個請求,需要在自己本地寫庫,還需要在 BCD 三個系統寫庫,自己本地寫庫要 3ms,BCD 三個系統分別寫庫要 300ms、450ms、200ms。最終請求總延時是 3 + 300 + 450 + 200 = 953ms,接近 1s,使用者感覺搞個什麼東西,慢死了慢死了。使用者通過瀏覽器發起請求,等待個 1s,這幾乎是不可接受的。

一般網際網路類的企業,對於使用者直接的操作,一般要求是每個請求都必須在 200 ms 以內完成,對使用者幾乎是無感知的。

如果使用 MQ,那麼 A 系統連續傳送 3 條訊息到 MQ 佇列中,假如耗時 5ms,A 系統從接受一個請求到返回響應給使用者,總時長是 3 + 5 = 8ms,對於使用者而言,其實感覺上就是點個按鈕,8ms 以後就直接返回了,爽!網站做得真好,真快!

削峰

每天 0:00 到 12:00,A 系統風平浪靜,每秒併發請求數量就 50 個。結果每次一到 12:00 ~ 13:00 ,每秒併發請求數量突然會暴增到 5k+ 條。但是系統是直接基於 MySQL 的,大量的請求湧入 MySQL,每秒鐘對 MySQL 執行約 5k 條 SQL。

一般的 MySQL,扛到每秒 2k 個請求就差不多了,如果每秒請求到 5k 的話,可能就直接把 MySQL 給打死了,導致系統崩潰,使用者也就沒法再使用系統了。

但是高峰期一過,到了下午的時候,就成了低峰期,可能也就 1w 的使用者同時在網站上操作,每秒中的請求數量可能也就 50 個請求,對整個系統幾乎沒有任何的壓力。

如果使用 MQ,每秒 5k 個請求寫入 MQ,A 系統每秒鐘最多處理 2k 個請求,因為 MySQL 每秒鐘最多處理 2k 個。A 系統從 MQ 中慢慢拉取請求,每秒鐘就拉取 2k 個請求,不要超過自己每秒能處理的最大請求數量就 ok,這樣下來,哪怕是高峰期的時候,A 系統也絕對不會掛掉。而 MQ 每秒鐘 5k 個請求進來,就 2k 個請求出去,結果就導致在中午高峰期(1 個小時),可能有幾十萬甚至幾百萬的請求積壓在 MQ 中。

這個短暫的高峰期積壓是 ok 的,因為高峰期過了之後,每秒鐘就 50 個請求進 MQ,但是 A 系統依然會按照每秒 2k 個請求的速度在處理。所以說,只要高峰期一過,A 系統就會快速將積壓的訊息給解決掉。

訊息佇列有什麼優缺點

優點上面已經說了,就是在特殊場景下有其對應的好處,解耦、非同步、削峰。

缺點有以下幾個:

  • 系統可用性降低

    系統引入的外部依賴越多,越容易掛掉。本來你就是 A 系統呼叫 BCD 三個系統的介面就好了,人 ABCD 四個系統好好的,沒啥問題,你偏加個 MQ 進來,萬一 MQ 掛了咋整,MQ 一掛,整套系統崩潰的,你不就完了?如何保證訊息佇列的高可用,可以點選這裡檢視。

  • 系統複雜度提高

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

  • 一致性問題

    A 系統處理完了直接返回成功了,人都以為你這個請求就成功了;但是問題是,要是 BCD 三個系統那裡,BD 兩個系統寫庫成功了,結果 C 系統寫庫失敗了,咋整?你這資料就不一致了。

所以訊息佇列實際是一種非常複雜的架構,你引入它有很多好處,但是也得針對它帶來的壞處做各種額外的技術方案和架構來規避掉,做好之後,你會發現,媽呀,系統複雜度提升了一個數量級,也許是複雜了 10 倍。但是關鍵時刻,用,還是得用的。

Kafka、ActiveMQ、RabbitMQ、RocketMQ 有什麼優缺點?

特性 ActiveMQ RabbitMQ RocketMQ Kafka
單機吞吐量 萬級,比 RocketMQ、Kafka 低一個數量級 同 ActiveMQ 10 萬級,支撐高吞吐 10 萬級,高吞吐,一般配合大資料類的系統來進行實時資料計算、日誌採集等場景
topic 數量對吞吐量的影響 topic 可以達到幾百/幾千的級別,吞吐量會有較小幅度的下降,這是 RocketMQ 的一大優勢,在同等機器下,可以支撐大量的 topic topic 從幾十到幾百個時候,吞吐量會大幅度下降,在同等機器下,Kafka 儘量保證 topic 數量不要過多,如果要支撐大規模的 topic,需要增加更多的機器資源
時效性 ms 級 微秒級,這是 RabbitMQ 的一大特點,延遲最低 ms 級 延遲在 ms 級以內
可用性 高,基於主從架構實現高可用 同 ActiveMQ 非常高,分散式架構 非常高,分散式,一個數據多個副本,少數機器宕機,不會丟失資料,不會導致不可用
訊息可靠性 有較低的概率丟失資料 基本不丟 經過引數優化配置,可以做到 0 丟失 同 RocketMQ
功能支援 MQ 領域的功能極其完備 基於 erlang 開發,併發能力很強,效能極好,延時很低 MQ 功能較為完善,還是分散式的,擴充套件性好 功能較為簡單,主要支援簡單的 MQ 功能,在大資料領域的實時計算以及日誌採集被大規模使用

綜上,各種對比之後,有如下建議:

一般的業務系統要引入 MQ,最早大家都用 ActiveMQ,但是現在確實大家用的不多了,沒經過大規模吞吐量場景的驗證,社群也不是很活躍,所以大家還是算了吧,我個人不推薦用這個了;

後來大家開始用 RabbitMQ,但是確實 erlang 語言阻止了大量的 Java 工程師去深入研究和掌控它,對公司而言,幾乎處於不可控的狀態,但是確實人家是開源的,比較穩定的支援,活躍度也高;

不過現在確實越來越多的公司會去用 RocketMQ,確實很不錯,畢竟是阿里出品,但社群可能有突然黃掉的風險(目前 RocketMQ 已捐給 Apache,但 GitHub 上的活躍度其實不算高)對自己公司技術實力有絕對自信的,推薦用 RocketMQ,否則回去老老實實用 RabbitMQ 吧,人家有活躍的開源社群,絕對不會黃。

所以中小型公司,技術實力較為一般,技術挑戰不是特別高,用 RabbitMQ 是不錯的選擇;大型公司,基礎架構研發實力較強,用 RocketMQ 是很好的選擇。

如果是大資料領域的實時計算、日誌採集等場景,用 Kafka 是業內標準的,絕對沒問題,社群活躍度很高,絕對不會黃,何況幾乎是全世界這個領域的事實性規範。

本文在米兜公眾號連結:
https://mp.weixin.qq.com/s/G24Upe0lSQhWVC8XQ5c1rA

歡迎關注米兜Java,一個注在共享、交流的Java學習平臺。

相關推薦

為什麼使用訊息佇列訊息佇列什麼優點缺點KafkaActiveMQRabbitMQRocketMQ 什麼優點缺點

面試題 為什麼使用訊息佇列? 訊息佇列有什麼優點和缺點? Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什麼區別,以及適合哪些場景? 面試官心理分析 其實面試官主要是想看看: 第一,你知不知道你們系統裡為什麼要用訊息佇列這個東西? 不少候選人,說自己專案裡用了 Redis、M

RPC協議http協議tcp/ip協議udp協議socket協議以及soap協議什麼相同點不同點

HTTP與RPC的區別: 人們常常錯誤地將HTTP稱作一種遠端過程呼叫(RPC)[23]機制,僅僅是因為它包括了請求和響應。    呼叫遠端機器上的一個過程(procedure)的觀念,是RPC與其他形式的基於網路的應用通訊的區別在。 RPC的協議識別出過程並且傳遞給它固定

客觀面試題--16.值傳遞引用傳遞的區別?JavaScript的資料型別什麼?

關於值傳遞和引用傳遞其實需要分情況看待.1.基本型別和引用型別在記憶體中的儲存Java中資料型別分為兩大類,基本型別和物件型別。相應的,變數也有兩種型別:基本型別和引用型別。基本型別的變數儲存原始值,即它代表的值就是數值本身;而引用型別的變數儲存引用值,"引用值"指向記憶體空

北京哪些打著招聘名義的培訓機構--軟體測試哪些?

作者:Dotest-與騰訊合作機構-零基礎軟體測試培訓 北京-打著招聘名義的培訓機構--軟體測試都有哪些? 首先申明下,雖然我也是做培訓軟體測試的,但是從來沒有用這招。因為我明白這是變相的欺騙;我知道在這麼冷的天氣,白跑一趟是多麼的--心冷;特別是抱著希望過去,您老卻是讓我培訓.......好無語!【要麼

RabbitMQ系列之七 分散式訊息佇列應用場景之非同步處理應用解耦流量削鋒訊息通訊理解分析

摘要:訊息佇列中介軟體是分散式系統中重要的元件,主要解決應用耦合,非同步訊息,流量削鋒等問題。實現高效能,高可用,可伸縮和最終一致性架構。是大型分散式系統不可缺少的中介軟體。 目前在生產環境,使用較多的訊息佇列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,

Python 訊息佇列rabbitmq使用之 更加細緻的 選擇的 釋出訊息/接收訊息

1、釋出端程式碼 # new_topic_p.py import pika import sys connection = pika.BlockingConnection(pika.Connec

訊息佇列概念使用場景 及ActiveMQ詳細入門使用教程

一、訊息佇列 訊息即是資訊的載體。為了讓訊息傳送者和訊息接收者都能夠明白訊息所承載的資訊(訊息傳送者需要知道如何構造訊息;訊息接收者需要知道如何解析訊息),它們就需要按照一種統一的格式描述訊息,這種統一的格式稱之為訊息協議。所以,有效的訊息一定具有某一種格式;而

【stark_summer的專欄 】專注於開發分散式任務排程框架分散式同步RPC非同步MQ訊息佇列、分散式日誌檢索框架hadoopsparkscala等技術 如果我的寫的文章能對您幫助,請您能給點捐助,請看首頁置頂

專注於開發分散式任務排程框架、分散式同步RPC、非同步MQ訊息佇列、分散式日誌檢索框架、hadoop、spark、scala等技術 如果我的寫的文章能對您有幫助,請您能給點捐助,請看首頁置頂...

訊息佇列MQ實踐----實現Queue(佇列訊息)Topic(主題訊息)兩種模式

之前有篇檔案介紹了生產消費者模式(http://blog.csdn.net/canot/article/details/51541920 ),當時是通過BlockingQueue阻塞佇列來實現,以及在Redis中使用pub/sub模式(http://blog.csdn.ne

(轉)ucos的事件 任務的通訊同步 訊號量 互斥量 訊息郵箱 訊息佇列

()    使一個等待超時的任務進入就緒狀態  事件控制塊連結串列也有空和工作中的2種區分,類似於任務控制塊,就不多說了 七、訊號量詳細 重要組成:型別    cnt     訊號量指標為空     控制塊 1.建立訊號量 OSSemCreat(cnt)------------設定型別 設定初始化計數 設定指

通過HTTP請求獲取RabbitMQ佇列訊息的方法

https://www.jianshu.com/p/9edf12944935 由於自動化測試的需要,現在要用一種簡單的方法可以獲取並驗證RabbitMQ中的訊息,而不是費勁通過程式再寫一個消費者。其實,RabbitMQ提供了HTTP API,可以幫助我們實現這個需求。 1. RabbitMQ

初探佇列訊息:普通http同步請求基於執行緒池的非同步請求基於訊息佇列的請求三者的比較

最近忙完了手頭的專案,終於有時間研究之前一直落下的訊息隊列了,順帶手又看了一下多執行緒非同步請求,加上最傳統的http同步請求,正好可以拉出來做個比較,廢話不多說,走起! 場景設計:三個使用者同時向系統傳送一個請求,要求系統進行處理; 通過這個場景設計,我們來看看不同請求方式的表現:

ActiveMQRabbitMQRocketMQKafka什麼優點缺點

ActiveMQ   單機吞吐量:萬級   topic數量都吞吐量的影響:   時效性:ms級   可用性:高,基於主從架構實現高可用性   訊息可靠性:有較低的概率丟失資料   功能支援:MQ領域的功能極其完備   總結:     非常成熟,功能強大,在早些年業內大量的公司以及專案中都有應用

mq訊息佇列 訊息佇列複習精講

訊息佇列複習精講 2018年11月30日 20:20:56 wonderful_life_mrchi 閱讀數:2 <spa

redis的佇列訊息實現應用解耦

過度耦合的缺點:php應用中,過度的耦合使得系統拓展性變弱,聯動性錯誤。 今天我給大家介紹的是利用redis的佇列訊息實現模組間的解耦。 應用場景:使用者在採購模組下單買了一批貨物回來,簽收時要在倉庫模組新增相應的庫存,普通的做法就是在簽收完成的時候通過介面給倉庫模組推送資料執行入庫操作。但是這麼做如果倉庫模

(六)RabbitMQ訊息佇列-訊息任務分發與訊息ACK確認機制(PHP版)

在前面一章介紹了在PHP中如何使用RabbitMQ,至此入門的的部分就完成了,我們內心中一定還有很多疑問:如果多個消費者消費同一個佇列怎麼辦?如果這幾個消費者分任務的權重不同怎麼辦?怎麼把同一個佇列不同級別的任務分發給不同的消費者?如果消費者異常離線怎麼辦?不要著急,後面將慢慢解開面紗。我們

Java訊息佇列總結只需一篇解決ActiveMQRabbitMQZeroMQKafka

一、訊息佇列概述 訊息佇列中介軟體是分散式系統中重要的元件,主要解決應用解耦,非同步訊息,流量削鋒等問題,實現高效能,高可用,可伸縮和最終一致性架構。目前使用較多的訊息佇列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ 二、

訊息中介軟體/佇列ActiveMQRabbitMQKafkaRocketMQZeroMq

Kafka最高,RabbitMq 次之, ActiveMq 最差。 2)吞吐量對比: kafka具有高的吞吐量,內部採用訊息的批量處理,zero-copy機制,資料的儲存和獲取是本地磁碟順序批量操作,具有O(1)的複雜度,訊息處理的效率很高。 rabbitMQ在吞吐量方面稍遜於kafka,他們的出發點不一樣,

RabbitMQ 訊息佇列佇列模型

RabbitMQ提供如下5種佇列模型 1.“Hello World!”. 簡單模式 2.Work Queues (又名: Task Queues) . 工作佇列,在消費者之間分配任務(競爭的消費者模式

shell指令碼監控rabbitmq佇列訊息數量(堵塞情況)

#!/bin/bash ################################################## # vim /etc/crontab # */30 * * * * root sh /mnt/rabbitmqMonitor/rabbitmq_monitor.cron #######