一筐高、消息隊列(MQ)概述
消息隊列(Message Queue),是分布式系統(tǒng)中重要的組件丑瞧,其通用的使用場景可以簡單地描述為:
當不需要立即獲得結(jié)果柑土,但是并發(fā)量又需要進行控制的時候,差不多就是需要使用消息隊列的時候绊汹。
消息隊列主要解決了應(yīng)用耦合稽屏、異步處理、流量削鋒等問題西乖。
當前使用較多的消息隊列有RabbitMQ狐榔、RocketMQ坛增、ActiveMQ、Kafka薄腻、ZeroMQ收捣、MetaMq等,而部分數(shù)據(jù)庫如Redis庵楷、Mysql以及phxsql也可實現(xiàn)消息隊列的功能罢艾。
二、消息隊列使用場景
消息隊列在實際應(yīng)用中包括如下四個場景:
應(yīng)用耦合:多應(yīng)用間通過消息隊列對同一消息進行處理嫁乘,避免調(diào)用接口失敗導致整個過程失斃バ觥;
異步處理:多應(yīng)用對消息隊列中同一消息進行處理蜓斧,應(yīng)用間并發(fā)處理消息仓蛆,相比串行處理,減少處理時間挎春;
限流削峰:廣泛應(yīng)用于秒殺或搶購活動中看疙,避免流量過大導致應(yīng)用系統(tǒng)掛掉的情況;
消息驅(qū)動的系統(tǒng):系統(tǒng)分為消息隊列直奋、消息生產(chǎn)者能庆、消息消費者,生產(chǎn)者負責產(chǎn)生消息脚线,消費者(可能有多個)負責對消息進行處理搁胆;
下面詳細介紹上述四個場景以及消息隊列如何在上述四個場景中使用:
2.1 異步處理
具體場景:用戶為了使用某個應(yīng)用,進行注冊邮绿,系統(tǒng)需要發(fā)送注冊郵件并驗證短信渠旁。對這兩個操作的處理方式有兩種:串行及并行。
(1)串行方式:新注冊信息生成后船逮,先發(fā)送注冊郵件顾腊,再發(fā)送驗證短信;
在這種方式下挖胃,需要最終發(fā)送驗證短信后再返回給客戶端杂靶。
(2)并行處理:新注冊信息寫入后,由發(fā)短信和發(fā)郵件并行處理酱鸭;
在這種方式下吗垮,發(fā)短信和發(fā)郵件 需處理完成后再返回給客戶端。
假設(shè)以上三個子系統(tǒng)處理的時間均為50ms凛辣,且不考慮網(wǎng)絡(luò)延遲抱既,則總的處理時間:
串行:50+50+50=150ms 并行:50+50 = 100ms
若使用消息隊列:
并在寫入消息隊列后立即返回成功給客戶端,則總的響應(yīng)時間依賴于寫入消息隊列的時間扁誓,而寫入消息隊列的時間本身是可以很快的防泵,基本可以忽略不計蚀之,因此總的處理時間相比串行提高了2倍,相比并行提高了一倍捷泞;
2.2 應(yīng)用耦合
具體場景:用戶使用QQ相冊上傳一張圖片足删,人臉識別系統(tǒng)會對該圖片進行人臉識別,一般的做法是锁右,服務(wù)器接收到圖片后失受,圖片上傳系統(tǒng)立即調(diào)用人臉識別系統(tǒng),調(diào)用完成后再返回成功咏瑟,如下圖所示:
該方法有如下缺點:
人臉識別系統(tǒng)被調(diào)失敗拂到,導致圖片上傳失敗码泞;
延遲高兄旬,需要人臉識別系統(tǒng)處理完成后,再返回給客戶端余寥,即使用戶并不需要立即知道結(jié)果领铐;
圖片上傳系統(tǒng)與人臉識別系統(tǒng)之間互相調(diào)用,需要做耦合宋舷;
若使用消息隊列:
客戶端上傳圖片后绪撵,圖片上傳系統(tǒng)將圖片信息如uin、批次寫入消息隊列祝蝠,直接返回成功音诈;而人臉識別系統(tǒng)則定時從消息隊列中取數(shù)據(jù),完成對新增圖片的識別绎狭。
此時圖片上傳系統(tǒng)并不需要關(guān)心人臉識別系統(tǒng)是否對這些圖片信息的處理改艇、以及何時對這些圖片信息進行處理。事實上坟岔,由于用戶并不需要立即知道人臉識別結(jié)果,人臉識別系統(tǒng)可以選擇不同的調(diào)度策略摔桦,按照閑時社付、忙時、正常時間邻耕,對隊列中的圖片信息進行處理鸥咖。
2.3 限流削峰
具體場景:購物網(wǎng)站開展秒殺活動,一般由于瞬時訪問量過大兄世,服務(wù)器接收過大啼辣,會導致流量暴增,相關(guān)系統(tǒng)無法處理請求甚至崩潰御滩。而加入消息隊列后鸥拧,系統(tǒng)可以從消息隊列中取數(shù)據(jù)党远,相當于消息隊列做了一次緩沖。
該方法有如下優(yōu)點:
請求先入消息隊列富弦,而不是由業(yè)務(wù)處理系統(tǒng)直接處理沟娱,做了一次緩沖,極大地減少了業(yè)務(wù)處理系統(tǒng)的壓力;
隊列長度可以做限制腕柜,事實上济似,秒殺時,后入隊列的用戶無法秒殺到商品盏缤,這些請求可以直接被拋棄砰蠢,返回活動已結(jié)束或商品已售完信息;
2.4 消息驅(qū)動的系統(tǒng)
具體場景:用戶新上傳了一批照片唉铜, 人臉識別系統(tǒng)需要對這個用戶的所有照片進行聚類台舱,聚類完成后由對賬系統(tǒng)重新生成用戶的人臉索引(加快查詢)。這三個子系統(tǒng)間由消息隊列連接起來打毛,前一個階段的處理結(jié)果放入隊列中柿赊,后一個階段從隊列中獲取消息繼續(xù)處理。
該方法有如下優(yōu)點:
避免了直接調(diào)用下一個系統(tǒng)導致當前系統(tǒng)失敾猛鳌碰声;
每個子系統(tǒng)對于消息的處理方式可以更為靈活,可以選擇收到消息時就處理熬甫,可以選擇定時處理胰挑,也可以劃分時間段按不同處理速度處理;
三椿肩、消息隊列的兩種模式
消息隊列包括兩種模式瞻颂,點對點模式(point to point, queue)和發(fā)布/訂閱模式(publish/subscribe郑象,topic)贡这。
3.1 點對點模式
點對點模式下包括三個角色:
消息隊列
發(fā)送者 (生產(chǎn)者)
接收者(消費者)
消息發(fā)送者生產(chǎn)消息發(fā)送到queue中,然后消息接收者從queue中取出并且消費消息厂榛。消息被消費以后盖矫,queue中不再有存儲,所以消息接收者不可能消費到已經(jīng)被消費的消息击奶。
點對點模式特點:
每個消息只有一個接收者(Consumer)(即一旦被消費辈双,消息就不再在消息隊列中);
發(fā)送者和接收者間沒有依賴性柜砾,發(fā)送者發(fā)送消息之后湃望,不管有沒有接收者在運行,都不會影響到發(fā)送者下次發(fā)送消息;
接收者在成功接收消息之后需向隊列應(yīng)答成功证芭,以便消息隊列刪除當前接收的消息瞳浦;
3.2 發(fā)布/訂閱模式
發(fā)布/訂閱模式下包括三個角色:
角色主題(Topic)
發(fā)布者(Publisher)
訂閱者(Subscriber)
發(fā)布者將消息發(fā)送到Topic,系統(tǒng)將這些消息傳遞給多個訂閱者。
發(fā)布/訂閱模式特點:
每個消息可以有多個訂閱者檩帐;
發(fā)布者和訂閱者之間有時間上的依賴性术幔。針對某個主題(Topic)的訂閱者,它必須創(chuàng)建一個訂閱者之后湃密,才能消費發(fā)布者的消息诅挑。
為了消費消息,訂閱者需要提前訂閱該角色主題泛源,并保持在線運行拔妥;
四、常用消息隊列介紹
本部分主要介紹四種常用的消息隊列(RabbitMQ/ActiveMQ/RocketMQ/Kafka)的主要特性达箍、優(yōu)點没龙、缺點。
4.1 RabbitMQ
RabbitMQ 2007年發(fā)布缎玫,是一個在AMQP(高級消息隊列協(xié)議)基礎(chǔ)上完成的硬纤,可復用的企業(yè)消息系統(tǒng),是當前最主流的消息中間件之一赃磨。
主要特性:
可靠性: 提供了多種技術(shù)可以讓你在性能和可靠性之間進行權(quán)衡筝家。這些技術(shù)包括持久性機制、投遞確認邻辉、發(fā)布者證實和高可用性機制溪王;
靈活的路由: 消息在到達隊列前是通過交換機進行路由的。RabbitMQ為典型的路由邏輯提供了多種內(nèi)置交換機類型值骇。如果你有更復雜的路由需求莹菱,可以將這些交換機組合起來使用,你甚至可以實現(xiàn)自己的交換機類型吱瘩,并且當做RabbitMQ的插件來使用道伟;
消息集群:在相同局域網(wǎng)中的多個RabbitMQ服務(wù)器可以聚合在一起,作為一個獨立的邏輯代理來使用使碾;
隊列高可用:隊列可以在集群中的機器上進行鏡像皱卓,以確保在硬件問題下還保證消息安全;
多種協(xié)議的支持:支持多種消息隊列協(xié)議部逮;
服務(wù)器端用Erlang語言編寫,支持只要是你能想到的所有編程語言嫂易;
管理界面: RabbitMQ有一個易用的用戶界面兄朋,使得用戶可以監(jiān)控和管理消息Broker的許多方面;
跟蹤機制:如果消息異常,RabbitMQ提供消息跟蹤機制颅和,使用者可以找出發(fā)生了什么傅事;
插件機制:提供了許多插件,來從多方面進行擴展峡扩,也可以編寫自己的插件蹭越;
使用RabbitMQ需要:
ErLang語言包
RabbitMQ安裝包
RabbitMQ可以運行在Erlang語言所支持的平臺之上:
Solaris
BSD
Linux
MacOSX
TRU64
Windows NT/2000/XP/Vista/Windows 7/Windows 8
Windows Server 2003/2008/2012
Windows 95, 98
VxWorks
優(yōu)點:
由于erlang語言的特性,mq 性能較好教届,高并發(fā)响鹃;
健壯、穩(wěn)定案训、易用买置、跨平臺、支持多種語言强霎、文檔齊全忿项;
有消息確認機制和持久化機制,可靠性高城舞;
高度可定制的路由轩触;
管理界面較豐富,在互聯(lián)網(wǎng)公司也有較大規(guī)模的應(yīng)用家夺;
社區(qū)活躍度高脱柱;
缺點:
盡管結(jié)合erlang語言本身的并發(fā)優(yōu)勢,性能較好秦踪,但是不利于做二次開發(fā)和維護褐捻;
實現(xiàn)了代理架構(gòu),意味著消息在發(fā)送到客戶端之前可以在中央節(jié)點上排隊椅邓。此特性使得RabbitMQ易于使用和部署柠逞,但是使得其運行速度較慢,因為中央節(jié)點增加了延遲景馁,消息封裝后也比較大板壮;
需要學習比較復雜的接口和協(xié)議,學習和維護成本較高合住;
4.2 ActiveMQ
ActiveMQ是由Apache出品绰精,ActiveMQ 是一個完全支持JMS1.1和J2EE 1.4規(guī)范的 JMS Provider實現(xiàn)。它非惩父穑快速笨使,支持多種語言的客戶端和協(xié)議,而且可以非常容易的嵌入到企業(yè)的應(yīng)用環(huán)境中僚害,并有許多高級功能硫椰。
主要特性:
服從 JMS 規(guī)范:JMS 規(guī)范提供了良好的標準和保證,包括:同步或異步的消息分發(fā),一次和僅一次的消息分發(fā)靶草,消息接收和訂閱等等蹄胰。遵從 JMS 規(guī)范的好處在于,不論使用什么 JMS 實現(xiàn)提供者奕翔,這些基礎(chǔ)特性都是可用的裕寨;
連接性:ActiveMQ 提供了廣泛的連接選項,支持的協(xié)議有:HTTP/S派继,IP 多播宾袜,SSL,STOMP互艾,TCP试和,UDP,XMPP等等纫普。對眾多協(xié)議的支持讓 ActiveMQ 擁有了很好的靈活性阅悍。
支持的協(xié)議種類多:OpenWire、STOMP昨稼、REST节视、XMPP、AMQP 假栓;
持久化插件和安全插件:ActiveMQ 提供了多種持久化選擇寻行。而且,ActiveMQ 的安全性也可以完全依據(jù)用戶需求進行自定義鑒權(quán)和授權(quán)匾荆;
支持的客戶端語言種類多:除了 Java 之外拌蜘,還有:C/C++,.NET牙丽,Perl简卧,PHP,Python烤芦,Ruby举娩;
代理集群:多個 ActiveMQ 代理可以組成一個集群來提供服務(wù);
異常簡單的管理:ActiveMQ 是以開發(fā)者思維被設(shè)計的构罗。所以铜涉,它并不需要專門的管理員,因為它提供了簡單又使用的管理特性遂唧。有很多中方法可以監(jiān)控 ActiveMQ 不同層面的數(shù)據(jù)芙代,包括使用在 JConsole 或者 ActiveMQ 的Web Console 中使用 JMX,通過處理 JMX 的告警消息盖彭,通過使用命令行腳本链蕊,甚至可以通過監(jiān)控各種類型的日志事甜。
使用ActiveMQ需要:
Java JDK
ActiveMQ安裝包
ActiveMQ可以運行在Java語言所支持的平臺之上。
優(yōu)點:
跨平臺(JAVA編寫與平臺無關(guān)有滔韵,ActiveMQ幾乎可以運行在任何的JVM上)
可以用JDBC:可以將數(shù)據(jù)持久化到數(shù)據(jù)庫。雖然使用JDBC會降低ActiveMQ的性能掌实,但是數(shù)據(jù)庫一直都是開發(fā)人員最熟悉的存儲介質(zhì)陪蜻。將消息存到數(shù)據(jù)庫,看得見摸得著贱鼻。而且公司有專門的DBA去對數(shù)據(jù)庫進行調(diào)優(yōu)宴卖,主從分離;
支持JMS :支持JMS的統(tǒng)一接口;
支持自動重連邻悬;
有安全機制:支持基于shiro症昏,jaas等多種安全配置機制,可以對Queue/Topic進行認證和授權(quán)父丰。
監(jiān)控完善:擁有完善的監(jiān)控肝谭,包括Web Console,JMX蛾扇,Shell命令行攘烛,Jolokia的REST API;
界面友善:提供的Web Console可以滿足大部分情況镀首,還有很多第三方的組件可以使用坟漱,如hawtio;
缺點:
社區(qū)活躍度不及RabbitMQ高更哄;
根據(jù)其他用戶反饋芋齿,會出莫名其妙的問題,會丟失消息成翩;
目前重心放到activemq6.0產(chǎn)品-apollo觅捆,對5.x的維護較少;
不適合用于上千個隊列的應(yīng)用場景捕传;
4.3 RocketMQ
RocketMQ出自 阿里公司的開源產(chǎn)品惠拭,用 Java 語言實現(xiàn),在設(shè)計時參考了 Kafka庸论,并做出了自己的一些改進职辅,消息可靠性上比 Kafka 更好。RocketMQ在阿里集團被廣泛應(yīng)用在訂單聂示,交易域携,充值,流計算鱼喉,消息推送秀鞭,日志流式處理趋观,binglog分發(fā)等場景。
主要特性:
是一個隊列模型的消息中間件锋边,具有高性能皱坛、高可靠、高實時豆巨、分布式特點剩辟;
Producer、Consumer往扔、隊列都可以分布式贩猎;
Producer向一些隊列輪流發(fā)送消息,隊列集合稱為Topic萍膛,Consumer如果做廣播消費吭服,則一個consumer實例消費這個Topic對應(yīng)的所有隊列,如果做集群消費蝗罗,則多個Consumer實例平均消費這個topic對應(yīng)的隊列集合艇棕;
能夠保證嚴格的消息順序;
提供豐富的消息拉取模式绿饵;
高效的訂閱者水平擴展能力欠肾;
實時的消息訂閱機制;
億級消息堆積能力拟赊;
較少的依賴刺桃;
使用RocketMQ需要:
Java JDK
安裝git、Maven
RocketMQ安裝包
RocketMQ可以運行在Java語言所支持的平臺之上吸祟。
優(yōu)點:
單機支持 1 萬以上持久化隊列
RocketMQ 的所有消息都是持久化的瑟慈,先寫入系統(tǒng) PAGECACHE,然后刷盤屋匕,可以保證內(nèi)存與磁盤都有一份數(shù)據(jù)葛碧,
訪問時,直接從內(nèi)存讀取过吻。
模型簡單进泼,接口易用(JMS 的接口很多場合并不太實用);
性能非常好纤虽,可以大量堆積消息在broker中乳绕;
支持多種消費,包括集群消費逼纸、廣播消費等洋措。
各個環(huán)節(jié)分布式擴展設(shè)計,主從HA杰刽;
開發(fā)度較活躍菠发,版本更新很快王滤。
缺點:
支持的客戶端語言不多,目前是java及c++滓鸠,其中c++不成熟雁乡;
RocketMQ社區(qū)關(guān)注度及成熟度也不及前兩者;
沒有web管理界面糜俗,提供了一個CLI(命令行界面)管理工具帶來查詢蔗怠、管理和診斷各種問題;
沒有在 mq 核心中去實現(xiàn)JMS等接口吩跋;
4.4 Kafka
Apache Kafka是一個分布式消息發(fā)布訂閱系統(tǒng)。它最初由LinkedIn公司基于獨特的設(shè)計實現(xiàn)為一個分布式的提交日志系統(tǒng)( a distributed commit log)渔工,锌钮,之后成為Apache項目的一部分。Kafka系統(tǒng)快速引矩、可擴展并且可持久化梁丘。它的分區(qū)特性,可復制和可容錯都是其不錯的特性旺韭。
主要特性:
快速持久化氛谜,可以在O(1)的系統(tǒng)開銷下進行消息持久化;
高吞吐区端,在一臺普通的服務(wù)器上既可以達到10W/s的吞吐速率值漫;
.完全的分布式系統(tǒng),Broker织盼、Producer杨何、Consumer都原生自動支持分布式,自動實現(xiàn)負載均衡沥邻;
支持同步和異步復制兩種HA危虱;
支持數(shù)據(jù)批量發(fā)送和拉取唐全;
zero-copy:減少IO操作步驟埃跷;
數(shù)據(jù)遷移、擴容對用戶透明邮利;
無需停機即可擴展機器弥雹;
其他特性:嚴格的消息順序、豐富的消息拉取模型近弟、高效訂閱者水平擴展缅糟、實時的消息訂閱、億級的消息堆積能力祷愉、定期刪除機制窗宦;
使用Kafka需要:
Java JDK
Kafka安裝包
優(yōu)點:
客戶端語言豐富赦颇,支持java、.net赴涵、php媒怯、ruby、python髓窜、go等多種語言扇苞;
性能卓越,單機寫入TPS約在百萬條/秒寄纵,消息大小10個字節(jié)鳖敷;
提供完全分布式架構(gòu), 并有replica機制, 擁有較高的可用性和可靠性, 理論上支持消息無限堆積;
支持批量操作程拭;
消費者采用Pull方式獲取消息, 消息有序, 通過控制能夠保證所有消息被消費且僅被消費一次;
有優(yōu)秀的第三方Kafka Web管理界面Kafka-Manager定踱;
在日志領(lǐng)域比較成熟,被多家公司和多個開源項目使用恃鞋;
缺點:
Kafka單機超過64個隊列/分區(qū)崖媚,Load會發(fā)生明顯的飆高現(xiàn)象,隊列越多恤浪,load越高畅哑,發(fā)送消息響應(yīng)時間變長
使用短輪詢方式,實時性取決于輪詢間隔時間水由;
消費失敗不支持重試荠呐;
支持消息順序,但是一臺代理宕機后绷杜,就會產(chǎn)生消息亂序直秆;
社區(qū)更新較慢;
4.5 RabbitMQ/ActiveMQ/RocketMQ/Kafka對比
這里列舉了上述四種消息隊列的差異對比:
結(jié)論:
Kafka在于分布式架構(gòu)鞭盟,RabbitMQ基于AMQP協(xié)議來實現(xiàn)圾结,RocketMQ/思路來源于kafka,改成了主從結(jié)構(gòu)齿诉,在事務(wù)性可靠性方面做了優(yōu)化筝野。廣泛來說,電商粤剧、金融等對事務(wù)性要求很高的歇竟,可以考慮RabbitMQ和RocketMQ,對性能要求高的可考慮Kafka抵恋。