在高并發(fā)業(yè)務(wù)場(chǎng)景下,消息隊(duì)列在流量削峰漩怎、解耦上有不可替代的作用勋颖。當(dāng)前使用較多的消息隊(duì)列有 RabbitMQ、RocketMQ勋锤、ActiveMQ饭玲、Kafka、ZeroMQ叁执、Pulsar 等茄厘。
消息隊(duì)列這么多,到底該選擇哪款消息隊(duì)列呢谈宛?
選擇消息隊(duì)列的基本標(biāo)準(zhǔn)
雖然這些消息隊(duì)列在功能和特性方面各有優(yōu)劣次哈,但我們?cè)谶x擇的時(shí)候要有一個(gè)基本標(biāo)準(zhǔn)。
首先吆录,必須是開(kāi)源的產(chǎn)品窑滞。開(kāi)源意味著,如果有一天你使用的消息隊(duì)列遇到了一個(gè)影響你系統(tǒng)業(yè)務(wù)的 Bug,至少還有機(jī)會(huì)通過(guò)修改源代碼來(lái)迅速修復(fù)或規(guī)避這個(gè) Bug哀卫,解決你的系統(tǒng)的問(wèn)題巨坊,而不是等待開(kāi)發(fā)者發(fā)布的下一個(gè)版本來(lái)解決。
其次聊训,這個(gè)產(chǎn)品必須是近年來(lái)比較流行并且有一定社區(qū)活躍度的產(chǎn)品抱究。流行的好處是恢氯,只要使用場(chǎng)景不太冷門带斑,遇到 Bug 的概率會(huì)非常低,因?yàn)榇蟛糠钟龅降?Bug勋拟,其他人早就遇到并且修復(fù)了勋磕。在使用過(guò)程中遇到的一些問(wèn)題,也比較容易在網(wǎng)上搜索到類似的問(wèn)題敢靡,然后很快的找到解決方案挂滓。還有一個(gè)優(yōu)勢(shì)就是,流行的產(chǎn)品與周邊生態(tài)系統(tǒng)會(huì)有一個(gè)比較好的集成和兼容啸胧。
最后赶站,作為一款及格的消息隊(duì)列,必須具備的幾個(gè)特性包括:
- 消息的可靠傳遞:確保不丟消息纺念;
- Cluster:支持集群贝椿,確保不會(huì)因?yàn)槟硞€(gè)節(jié)點(diǎn)宕機(jī)導(dǎo)致服務(wù)不可用,當(dāng)然也不能丟消息陷谱;
- 性能:具備足夠好的性能烙博,能滿足絕大多數(shù)場(chǎng)景的性能要求。
接下來(lái)看一下有哪些符合上面這些條件烟逊,可供選擇的開(kāi)源消息隊(duì)列渣窜。
RabbitMQ
首先,我們來(lái)看下消息隊(duì)列 RabbitMQ宪躯。RabbitMQ 于 2007 年發(fā)布乔宿,是使用 Erlang 編程語(yǔ)言編寫的,最早是為電信行業(yè)系統(tǒng)之間的可靠通信設(shè)計(jì)的访雪,也是少數(shù)幾個(gè)支持 AMQP 協(xié)議的消息隊(duì)列之一详瑞。
RabbitMQ:輕量級(jí)、迅捷冬阳,它的宣傳口號(hào)蛤虐,也很明確地表明了 RabbitMQ 的特點(diǎn):Messaging that just works,開(kāi)箱即用的消息隊(duì)列肝陪。也就是說(shuō)驳庭,RabbitMQ 是一個(gè)相當(dāng)輕量級(jí)的消息隊(duì)列,非常容易部署和使用。
RabbitMQ 一個(gè)比較有特色的功能是支持非常靈活的路由配置饲常,和其他消息隊(duì)列不同的是蹲堂,它在生產(chǎn)者(Producer)和隊(duì)列(Queue)之間增加了一個(gè) Exchange 模塊,可以理解為交換機(jī)贝淤。
Exchange 模塊的作用和交換機(jī)非常相似柒竞,根據(jù)配置的路由規(guī)則將生產(chǎn)者發(fā)出的消息分發(fā)到不同的隊(duì)列中。路由的規(guī)則也非常靈活播聪,甚至可以自己來(lái)實(shí)現(xiàn)路由規(guī)則朽基。如果正好需要這個(gè)功能,RabbitMQ 是個(gè)不錯(cuò)的選擇离陶。
RabbitMQ 的客戶端支持的編程語(yǔ)言大概是所有消息隊(duì)列中最多的稼虎。
接下來(lái)說(shuō)下 RabbitMQ 的幾個(gè)問(wèn)題:
- RabbitMQ 對(duì)消息堆積的支持并不好,當(dāng)大量消息積壓的時(shí)候招刨,會(huì)導(dǎo)致 RabbitMQ 的性能急劇下降霎俩。
- RabbitMQ 的性能是這幾個(gè)消息隊(duì)列中最差的,大概每秒鐘可以處理幾萬(wàn)到十幾萬(wàn)條消息沉眶。如果應(yīng)用對(duì)消息隊(duì)列的性能要求非常高打却,那不要選擇 RabbitMQ。
- RabbitMQ 使用的編程語(yǔ)言 Erlang谎倔,擴(kuò)展和二次開(kāi)發(fā)成本高柳击。
RocketMQ
RocketMQ 是阿里巴巴在 2012 年開(kāi)源的消息隊(duì)列產(chǎn)品,用 Java 語(yǔ)言實(shí)現(xiàn)传藏,在設(shè)計(jì)時(shí)參考了 Kafka腻暮,并做出了自己的一些改進(jìn),后來(lái)捐贈(zèng)給 Apache 軟件基金會(huì)毯侦,2017 正式畢業(yè)哭靖,成為 Apache 的頂級(jí)項(xiàng)目。RocketMQ 在阿里內(nèi)部被廣泛應(yīng)用在訂單侈离,交易试幽,充值,流計(jì)算卦碾,消息推送铺坞,日志流式處理,Binglog 分發(fā)等場(chǎng)景洲胖。經(jīng)歷過(guò)多次雙十一考驗(yàn)济榨,它的性能、穩(wěn)定性和可靠性都是值得信賴的绿映。
RocketMQ 有著不錯(cuò)的性能擒滑,穩(wěn)定性和可靠性腐晾,具備一個(gè)現(xiàn)代的消息隊(duì)列應(yīng)該有的幾乎全部功能和特性,并且它還在持續(xù)的成長(zhǎng)中丐一。
RocketMQ 有非吃逄牵活躍的中文社區(qū),大多數(shù)問(wèn)題可以找到中文的答案库车。RocketMQ 使用 Java 語(yǔ)言開(kāi)發(fā)巨柒,源代碼相對(duì)比較容易讀懂,容易對(duì) RocketMQ 進(jìn)行擴(kuò)展或者二次開(kāi)發(fā)柠衍。
RocketMQ 對(duì)在線業(yè)務(wù)的響應(yīng)時(shí)延做了很多的優(yōu)化洋满,大多數(shù)情況下可以做到毫秒級(jí)的響應(yīng),如果你的應(yīng)用場(chǎng)景很在意響應(yīng)時(shí)延拧略,那應(yīng)該選擇使用 RocketMQ芦岂。
RocketMQ 的性能比 RabbitMQ 要高一個(gè)數(shù)量級(jí)瘪弓,每秒鐘大概能處理幾十萬(wàn)條消息垫蛆。
RocketMQ 的劣勢(shì)是與周邊生態(tài)系統(tǒng)的集成和兼容程度不夠。
Kafka
Apache Kafka 是一個(gè)分布式消息發(fā)布訂閱系統(tǒng)腺怯。它最初由 LinkedIn 公司基于獨(dú)特的設(shè)計(jì)實(shí)現(xiàn)為一個(gè)分布式的日志提交系統(tǒng)袱饭,之后成為 Apache 項(xiàng)目的一部分。
在早期的版本中呛占,為了獲得極致的性能虑乖,在設(shè)計(jì)方面做了很多的犧牲,比如不保證消息的可靠性晾虑,可能會(huì)丟失消息疹味,也不支持集群,功能上也比較簡(jiǎn)陋帜篇,這些犧牲對(duì)于處理海量日志這個(gè)特定的場(chǎng)景都是可以接受的糙捺。
但是,隨后幾年 Kafka 逐步補(bǔ)齊了這些短板笙隙,當(dāng)下的 Kafka 已經(jīng)發(fā)展為一個(gè)非常成熟的消息隊(duì)列產(chǎn)品洪灯,無(wú)論在數(shù)據(jù)可靠性、穩(wěn)定性和功能特性等方面都可以滿足絕大多數(shù)場(chǎng)景的需求竟痰。
Kafka 與周邊生態(tài)系統(tǒng)的兼容性是最好的沒(méi)有之一签钩,尤其在大數(shù)據(jù)和流計(jì)算領(lǐng)域,幾乎所有的相關(guān)開(kāi)源軟件系統(tǒng)都會(huì)優(yōu)先支持 Kafka坏快。
Kafka 性能高效铅檩、可擴(kuò)展良好并且可持久化。它的分區(qū)特性莽鸿,可復(fù)制和可容錯(cuò)都是不錯(cuò)的特性昧旨。
Kafka 使用 Scala 和 Java 語(yǔ)言開(kāi)發(fā),設(shè)計(jì)上大量使用了批量和異步的思想,使得 Kafka 能做到超高的性能臼予。Kafka 的性能鸣戴,尤其是異步收發(fā)的性能,是三者中最好的粘拾,但與 RocketMQ 并沒(méi)有量級(jí)上的差異窄锅,大約每秒鐘可以處理幾十萬(wàn)條消息。
在有足夠的客戶端并發(fā)進(jìn)行異步批量發(fā)送缰雇,并且開(kāi)啟壓縮的情況下入偷,Kafka 的極限處理能力可以超過(guò)每秒 2000 萬(wàn)條消息。
但是 Kafka 異步批量的設(shè)計(jì)帶來(lái)的問(wèn)題是械哟,它的同步收發(fā)消息的響應(yīng)時(shí)延比較高疏之,因?yàn)楫?dāng)客戶端發(fā)送一條消息的時(shí)候,Kafka 并不會(huì)立即發(fā)送出去暇咆,而是要等一會(huì)兒攢一批再發(fā)送锋爪,在它的 Broker 中,很多地方都會(huì)使用這種先攢一波再一起處理的設(shè)計(jì)爸业。當(dāng)你的業(yè)務(wù)場(chǎng)景中其骄,每秒鐘消息數(shù)量沒(méi)有那么多的時(shí)候,Kafka 的時(shí)延反而會(huì)比較高扯旷。所以拯爽,Kafka 不太適合在線業(yè)務(wù)場(chǎng)景。
消息隊(duì)列對(duì)比
Kafka | RocketMQ | RabbitMQ | |
---|---|---|---|
單機(jī)吞吐量 | 十萬(wàn)級(jí) | 十萬(wàn)級(jí) | 萬(wàn)級(jí) |
開(kāi)發(fā)語(yǔ)言 | Java & Scala | Java | Erlang |
消息延遲 | 毫秒級(jí) | 毫秒級(jí) | 微秒級(jí) |
消息丟失 | 參數(shù)優(yōu)化配置后可做到0丟失 | 參數(shù)優(yōu)化配置后可做到0丟失 | 有較低的概率丟失 |
消費(fèi)模式 | Pull | Pull+Push | Pull+Push |
topic數(shù)量對(duì)吞吐量的影響 | topic達(dá)到幾十钧忽,幾百個(gè)時(shí)毯炮,吞吐量會(huì)大幅度下降 | topic達(dá)到幾百,幾千個(gè)時(shí)耸黑,吞吐量會(huì)有較小幅度的下降 | \ |
可用性 | 非常高(分布式) | 非常高(主從) | 高(主從) |
總結(jié) | 吞吐量高桃煎,微秒級(jí)延時(shí),分布式高可用崎坊,最好是支持較少topic數(shù)量备禀,會(huì)有消息重復(fù)現(xiàn)象 | 可支撐大規(guī)模topic數(shù)量,方便二次開(kāi)發(fā)和擴(kuò)展 | 不支持集群動(dòng)態(tài)擴(kuò)容奈揍,擴(kuò)展和二次開(kāi)發(fā)難 |
總結(jié)
本文分別介紹了 RabbitMQ曲尸,RocketMQ 和 Kafka 幾種常見(jiàn)的消息隊(duì)列,闡述了各種消息隊(duì)列的主要特點(diǎn)和優(yōu)劣勢(shì)男翰。
在了解了上面這些開(kāi)源消息隊(duì)列各自的特點(diǎn)和優(yōu)劣勢(shì)后另患,對(duì)于消息隊(duì)列及相關(guān)技術(shù)選型,相信你會(huì)有更深入的理解和認(rèn)識(shí)蛾绎。以下幾條選擇的建議可以參考:
- 如果消息隊(duì)列不是將要構(gòu)建系統(tǒng)的重點(diǎn)昆箕,對(duì)消息隊(duì)列功能和性能沒(méi)有很高的要求鸦列,只需要一個(gè)快速上手易于維護(hù)的消息隊(duì)列,建議使用 RabbitMQ鹏倘。
- 如果系統(tǒng)使用消息隊(duì)列主要場(chǎng)景是處理在線業(yè)務(wù)薯嗤,比如在交易系統(tǒng)中用消息隊(duì)列傳遞訂單,需要低延遲和高穩(wěn)定性纤泵,建議使用 RocketMQ骆姐。
- 如果需要處理海量的消息,像收集日志捏题、監(jiān)控信息或是埋點(diǎn)這類數(shù)據(jù)玻褪,或是你的應(yīng)用場(chǎng)景大量使用了大數(shù)據(jù)、流計(jì)算相關(guān)的開(kāi)源產(chǎn)品公荧,那 Kafka 是最適合的消息隊(duì)列带射。
每一個(gè)消息隊(duì)列都有自己的優(yōu)劣勢(shì),需要根據(jù)現(xiàn)有系統(tǒng)的情況循狰,選擇最適合的消息隊(duì)列窟社,更多細(xì)節(jié)和原理性的東西,還需在實(shí)踐中見(jiàn)真知晤揣!
參考
歡迎關(guān)注我的公眾號(hào):武培軒桥爽,獲得獨(dú)家整理的學(xué)習(xí)資源和日常干貨推送。