一、為什么使用消息隊列
核心的有3個:解耦、異步、削峰
- 解耦:一個系統(tǒng)或者一個模塊,調(diào)用了多個系統(tǒng)或者模塊,互相之間的調(diào)用很復(fù)雜,維護(hù)起來很麻煩。如果這個調(diào)用不需要直接同步調(diào)用接口的,就可以考慮用MQ給他異步化解耦。
- 異步:A系統(tǒng)接收一個請求,需要在自己本地寫庫,還需要在BCD三個系統(tǒng)寫庫,自己本地寫庫要3ms,BCD三個系統(tǒng)分別寫庫要300ms、450ms、200ms。最終請求總延時是3 + 300 + 450 + 200 = 953ms,接近1s,如果用mq,只需要寫本地庫+寫mq,BCD自行從mq中讀取寫庫。
- 削峰:當(dāng)系統(tǒng)在某一點有大量請求涌入,峰值過大,遠(yuǎn)遠(yuǎn)超過系統(tǒng)承受力,系統(tǒng)就會hang死
二、消息隊列優(yōu)缺點
- 系統(tǒng)可用性降低:系統(tǒng)引入的外部依賴越多,越容易掛掉。一旦MQ掛了,其他系統(tǒng)就不能消費數(shù)據(jù),整個系統(tǒng)就崩潰了。
- 系統(tǒng)復(fù)雜性提高:加個MQ進(jìn)來,怎么保證消息沒有重復(fù)消費?怎么處理消息丟失的情況?怎么保證消息傳遞的順序性?等等...
- 一致性問題:A系統(tǒng)處理完了直接返回成功了,人都以為你這個請求就成功了,但是問題是,要是BCD三個系統(tǒng)那里,BD兩個系統(tǒng)寫庫成功了,結(jié)果C系統(tǒng)寫庫失敗了,這就出現(xiàn)數(shù)據(jù)不一致問題。
三 、kafka、activemq、rabbitmq、rocketmq比較
| 特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka |
|---|---|---|---|---|
| 單機(jī)吞吐量 | 萬級,吞吐量比RocketMQ和Kafka要低了一個數(shù)量級 | 萬級,吞吐量比RocketMQ和Kafka要低了一個數(shù)量級 | 10萬級,RocketMQ也是可以支撐高吞吐的一種MQ | 10萬級別,這是kafka最大的優(yōu)點,就是吞吐量高。 一般配合大數(shù)據(jù)類的系統(tǒng)來進(jìn)行實時數(shù)據(jù)計算、日志采集等場景 |
| topic數(shù)量對吞吐量的影響 | topic可以達(dá)到幾百,幾千個的級別,吞吐量會有較小幅度的下降。 這是RocketMQ的一大優(yōu)勢,在同等機(jī)器下,可以支撐大量的topic |
topic從幾十個到幾百個的時候,吞吐量會大幅度下降。 所以在同等機(jī)器下,kafka盡量保證topic數(shù)量不要過多。如果要支撐大規(guī)模topic,需要增加更多的機(jī)器資源 |
||
| 時效性 | ms級 | 微秒級,這是rabbitmq的一大特點,延遲是最低的 | ms級 | 延遲在ms級以內(nèi) |
| 可用性 | 高,基于主從架構(gòu)實現(xiàn)高可用性 | 高,基于主從架構(gòu)實現(xiàn)高可用性 | 高,基于主從架構(gòu)實現(xiàn)高可用性 | 非常高,kafka是分布式的,一個數(shù)據(jù)多個副本,少數(shù)機(jī)器宕機(jī),不會丟失數(shù)據(jù),不會導(dǎo)致不可用 |
| 消息可靠性 | 有較低的概率丟失數(shù)據(jù) | 經(jīng)過參數(shù)優(yōu)化配置,可以做到0丟失 | 經(jīng)過參數(shù)優(yōu)化配置,消息可以做到0丟失 | |
| 功能支持 | MQ領(lǐng)域的功能極其完備 | 基于erlang開發(fā),所以并發(fā)能力很強,性能極其好,延時很低 | MQ功能較為完善,還是分布式的,擴(kuò)展性好 | 功能較為簡單,主要支持簡單的MQ功能,在大數(shù)據(jù)領(lǐng)域的實時計算以及日志采集被大規(guī)模使用,是事實上的標(biāo)準(zhǔn) |
| 優(yōu)劣勢總結(jié) | 非常成熟,功能強大,在業(yè)內(nèi)大量的公司以及項目中都有應(yīng)用 偶爾會有較低概率丟失消息 而且現(xiàn)在社區(qū)以及國內(nèi)應(yīng)用都越來越少,官方社區(qū)現(xiàn)在對ActiveMQ 5.x維護(hù)越來越少,幾個月才發(fā)布一個版本 而且確實主要是基于解耦和異步來用的,較少在大規(guī)模吞吐的場景中使用 |
erlang語言開發(fā),性能極其好,延時很低; 吞吐量到萬級,MQ功能比較完備 而且開源提供的管理界面非常棒,用起來很好用 社區(qū)相對比較活躍,幾乎每個月都發(fā)布幾個版本分 在國內(nèi)一些互聯(lián)網(wǎng)公司近幾年用rabbitmq也比較多一些 但是問題也是顯而易見的,RabbitMQ確實吞吐量會低一些,這是因為他做的實現(xiàn)機(jī)制比較重。 而且erlang開發(fā),很難去看懂源碼,對它的掌控很弱,基本只能依賴于開源社區(qū)的快速維護(hù)和修復(fù)bug。 而且rabbitmq集群動態(tài)擴(kuò)展會很麻煩。 |
接口簡單易用,而且畢竟在阿里大規(guī)模應(yīng)用過,有阿里品牌保障 日處理消息上百億之多,可以做到大規(guī)模吞吐,性能也非常好,分布式擴(kuò)展也很方便,社區(qū)維護(hù)還可以,可靠性和可用性都是ok的,還可以支撐大規(guī)模的topic數(shù)量,支持復(fù)雜MQ業(yè)務(wù)場景 而且一個很大的優(yōu)勢在于,阿里出品都是java系的,可以自己閱讀源碼,定制自己公司的MQ,可以掌控 社區(qū)活躍度相對較為一般,文檔相對來說簡單一些,然后接口這塊不是按照標(biāo)準(zhǔn)JMS規(guī)范走的有些系統(tǒng)要遷移需要修改大量代碼 還有就是阿里出臺的技術(shù),可能面臨技術(shù)被拋棄,社區(qū)黃掉的風(fēng)險,但如果公司有技術(shù)實力用RocketMQ挺好 |
僅僅提供較少的核心功能,但是提供超高的吞吐量,ms級的延遲,極高的可用性以及可靠性,而且分布式可以任意擴(kuò)展 同時kafka最好是支撐較少的topic數(shù)量即可,保證其超高吞吐量 而且kafka唯一的一點劣勢是有可能消息重復(fù)消費,那么對數(shù)據(jù)準(zhǔn)確性會造成極其輕微的影響,在大數(shù)據(jù)領(lǐng)域中以及日志采集中,這點輕微影響可以忽略 這個特性天然適合大數(shù)據(jù)實時計算以及日志收集 |
總結(jié):
中小型公司,技術(shù)實力較為一般,技術(shù)挑戰(zhàn)不是特別高,用RabbitMQ是不錯的選擇;大型公司,基礎(chǔ)架構(gòu)研發(fā)實力較強,用RocketMQ是很好的選擇
如果是大數(shù)據(jù)領(lǐng)域的實時計算、日志采集等場景,用Kafka是業(yè)內(nèi)標(biāo)準(zhǔn)