文章大綱
一、什么是消息中間件
二、消息中間件組成
三、消息隊(duì)列的的傳輸模式
四、消息中間件的優(yōu)勢(shì)
五、消息中間件應(yīng)用場(chǎng)景
六、消息中間件常用協(xié)議
七、常見消息中間件介紹與比較
八、參考文章

一、什么是消息中間件
??消息隊(duì)列已經(jīng)逐漸成為企業(yè)IT系統(tǒng)內(nèi)部通信的核心手段。它具有低耦合、可靠投遞、廣播、流量控制、最終一致性等一系列功能,成為異步RPC的主要手段之一。當(dāng)今市面上有很多主流的消息中間件,如老牌的ActiveMQ、RabbitMQ,炙手可熱的Kafka,阿里巴巴自主開發(fā)RocketMQ等。
二、消息中間件組成
1. Broker
消息服務(wù)器,為server提供消息核心服務(wù)
2. Producer
消息生產(chǎn)者,業(yè)務(wù)的發(fā)起方,負(fù)責(zé)生產(chǎn)消息傳輸給broker
3. Consumer
消息消費(fèi)者,業(yè)務(wù)的處理方,負(fù)責(zé)從broker獲取消息并進(jìn)行業(yè)務(wù)邏輯處理
4. Topic
主題,發(fā)布訂閱模式下的消息統(tǒng)一匯集地,不同生產(chǎn)者向topic發(fā)送消息,由MQ服務(wù)器分發(fā)到不同的訂閱者,實(shí)現(xiàn)消息的廣播
5. Queue
隊(duì)列,PTP模式下,特定生產(chǎn)者向特定queue發(fā)送消息,消費(fèi)者訂閱特定的queue完成指定消息的接收
6. Message
消息體,根據(jù)不同通信協(xié)議定義的固定格式進(jìn)行編碼的數(shù)據(jù)包,來(lái)封裝業(yè)務(wù)數(shù)據(jù),實(shí)現(xiàn)消息的傳輸
三、消息隊(duì)列的的傳輸模式
1. 點(diǎn)對(duì)點(diǎn)
點(diǎn)對(duì)點(diǎn)模型 用于 消息生產(chǎn)者 和 消息消費(fèi)者 之間 點(diǎn)到點(diǎn) 的通信。消息生產(chǎn)者將消息發(fā)送到由某個(gè)名字標(biāo)識(shí)的特定消費(fèi)者。這個(gè)名字實(shí)際上對(duì)于消費(fèi)服務(wù)中的一個(gè) 隊(duì)列(Queue),在消息傳遞給消費(fèi)者之前它被 存儲(chǔ) 在這個(gè)隊(duì)列中。隊(duì)列消息 可以放在 內(nèi)存 中也可以 持久化,以保證在消息服務(wù)出現(xiàn)故障時(shí)仍然能夠傳遞消息。
傳統(tǒng)的點(diǎn)對(duì)點(diǎn)消息中間件通常由 消息隊(duì)列服務(wù)、消息傳遞服務(wù)、消息隊(duì)列 和 消息應(yīng)用程序接口 API 組成,其典型的結(jié)構(gòu)如下圖所示。

特點(diǎn)
每個(gè)消息只用一個(gè)消費(fèi)者;
發(fā)送者和接受者沒有時(shí)間依賴;
接受者確認(rèn)消息接受和處理成功。
示意圖如下所示

2. 發(fā)布/訂閱模型(Pub/Sub)
發(fā)布者/訂閱者 模型支持向一個(gè)特定的 消息主題 生產(chǎn)消息。0 或 多個(gè)訂閱者 可能對(duì)接收來(lái)自 特定消息主題 的消息感興趣。
在這種模型下,發(fā)布者和訂閱者彼此不知道對(duì)方,就好比是匿名公告板。這種模式被概況為:多個(gè)消費(fèi)者可以獲得消息,在 發(fā)布者 和 訂閱者 之間存在 時(shí)間依賴性。發(fā)布者需要建立一個(gè) 訂閱(subscription),以便能夠消費(fèi)者訂閱。訂閱者 必須保持 持續(xù)的活動(dòng)狀態(tài) 并 接收消息。
在這種情況下,在訂閱者 未連接時(shí),發(fā)布的消息將在訂閱者 重新連接 時(shí) 重新發(fā)布,如下圖所示:

特性
每個(gè)消息可以有多個(gè)訂閱者;
客戶端只有訂閱后才能接收到消息;
持久訂閱和非持久訂閱。
注意
發(fā)布者和訂閱者有時(shí)間依賴:接受者和發(fā)布者只有建立訂閱關(guān)系才能收到消息;
持久訂閱:訂閱關(guān)系建立后,消息就不會(huì)消失,不管訂閱者是否都在線;
非持久訂閱:訂閱者為了接受消息,必須一直在線。當(dāng)只有一個(gè)訂閱者時(shí)約等于點(diǎn)對(duì)點(diǎn)模式
四、消息中間件的優(yōu)勢(shì)
1. 系統(tǒng)解耦
交互系統(tǒng)之間沒有直接的調(diào)用關(guān)系,只是通過(guò)消息傳輸,故系統(tǒng)侵入性不強(qiáng),耦合度低。
2. 提高系統(tǒng)響應(yīng)時(shí)間
例如原來(lái)的一套邏輯,完成支付可能涉及先修改訂單狀態(tài)、計(jì)算會(huì)員積分、通知物流配送幾個(gè)邏輯才能完成;通過(guò)MQ架構(gòu)設(shè)計(jì),就可將緊急重要(需要立刻響應(yīng))的業(yè)務(wù)放到該調(diào)用方法中,響應(yīng)要求不高的使用消息隊(duì)列,放到MQ隊(duì)列中,供消費(fèi)者處理。
3. 為大數(shù)據(jù)處理架構(gòu)提供服務(wù)
通過(guò)消息作為整合,大數(shù)據(jù)的背景下,消息隊(duì)列還與實(shí)時(shí)處理架構(gòu)整合,為數(shù)據(jù)處理提供性能支持。
4. Java消息服務(wù)——JMS
Java消息服務(wù)(Java Message Service,JMS)應(yīng)用程序接口是一個(gè)Java平臺(tái)中關(guān)于面向消息中間件(MOM)的API,用于在兩個(gè)應(yīng)用程序之間,或分布式系統(tǒng)中發(fā)送消息,進(jìn)行異步通信。
JMS中的P2P和Pub/Sub消息模式:點(diǎn)對(duì)點(diǎn)(point to point, queue)與發(fā)布訂閱(publish/subscribe,topic)最初是由JMS定義的。這兩種模式主要區(qū)別或解決的問題就是發(fā)送到隊(duì)列的消息能否重復(fù)消費(fèi)(多訂閱)。
五、消息中間件應(yīng)用場(chǎng)景
當(dāng)你需要使用 消息隊(duì)列 時(shí),首先需要考慮它的必要性??梢允褂孟㈥?duì)列的場(chǎng)景有很多,最常用的幾種,是做 應(yīng)用程序松耦合、異步處理模式、發(fā)布與訂閱、最終一致性、錯(cuò)峰流控 和 日志緩沖 等。反之,如果需要 強(qiáng)一致性,關(guān)注業(yè)務(wù)邏輯的處理結(jié)果,則使用 RPC 顯得更為合適。
1. 異步處理
1.1 介紹
有些業(yè)務(wù)不想也不需要立即處理消息。消息隊(duì)列提供了異步處理機(jī)制,允許用戶把一個(gè)消息放入隊(duì)列,但并不立即處理它。想向隊(duì)列中放入多少消息就放多少,然后在需要的時(shí)候再去處理它們。
1.2 具體場(chǎng)景
用戶為了使用某個(gè)應(yīng)用,進(jìn)行注冊(cè),系統(tǒng)需要發(fā)送注冊(cè)郵件并驗(yàn)證短信。對(duì)這兩個(gè)操作的處理方式有兩種:串行及并行。
(1)串行方式:新注冊(cè)信息生成后,先發(fā)送注冊(cè)郵件,再發(fā)送驗(yàn)證短信;

在這種方式下,需要最終發(fā)送驗(yàn)證短信后再返回給客戶端。
(2)并行處理:新注冊(cè)信息寫入后,由發(fā)短信和發(fā)郵件并行處理;

在這種方式下,發(fā)短信和發(fā)郵件 需處理完成后再返回給客戶端。
假設(shè)以上三個(gè)子系統(tǒng)處理的時(shí)間均為50ms,且不考慮網(wǎng)絡(luò)延遲,則總的處理時(shí)間:
串行:50+50+50=150ms 并行:50+50 = 100ms
若使用消息隊(duì)列:

并在寫入消息隊(duì)列后立即返回成功給客戶端,則總的響應(yīng)時(shí)間依賴于寫入消息隊(duì)列的時(shí)間,而寫入消息隊(duì)列的時(shí)間本身是可以很快的,基本可以忽略不計(jì),因此總的處理時(shí)間相比串行提高了2倍,相比并行提高了一倍;
2. 應(yīng)用耦合
2.1 介紹
交互系統(tǒng)之間沒有直接的調(diào)用關(guān)系,只是通過(guò)消息傳輸,故系統(tǒng)侵入性不強(qiáng),耦合度低。
2.2 具體場(chǎng)景
用戶使用QQ相冊(cè)上傳一張圖片,人臉識(shí)別系統(tǒng)會(huì)對(duì)該圖片進(jìn)行人臉識(shí)別,一般的做法是,服務(wù)器接收到圖片后,圖片上傳系統(tǒng)立即調(diào)用人臉識(shí)別系統(tǒng),調(diào)用完成后再返回成功,如下圖所示:

該方法有如下缺點(diǎn):
(1)人臉識(shí)別系統(tǒng)被調(diào)失敗,導(dǎo)致圖片上傳失?。?br>
(2)延遲高,需要人臉識(shí)別系統(tǒng)處理完成后,再返回給客戶端,即使用戶并不需要立即知道結(jié)果;
(3)圖片上傳系統(tǒng)與人臉識(shí)別系統(tǒng)之間互相調(diào)用,需要做耦合;
若使用消息隊(duì)列:

客戶端上傳圖片后,圖片上傳系統(tǒng)將圖片信息如uin、批次寫入消息隊(duì)列,直接返回成功;而人臉識(shí)別系統(tǒng)則定時(shí)從消息隊(duì)列中取數(shù)據(jù),完成對(duì)新增圖片的識(shí)別。
此時(shí)圖片上傳系統(tǒng)并不需要關(guān)心人臉識(shí)別系統(tǒng)是否對(duì)這些圖片信息的處理、以及何時(shí)對(duì)這些圖片信息進(jìn)行處理。事實(shí)上,由于用戶并不需要立即知道人臉識(shí)別結(jié)果,人臉識(shí)別系統(tǒng)可以選擇不同的調(diào)度策略,按照閑時(shí)、忙時(shí)、正常時(shí)間,對(duì)隊(duì)列中的圖片信息進(jìn)行處理。
3. 流量削峰和流控
3.1 介紹
當(dāng)上下游系統(tǒng) 處理能力存在差距的時(shí)候,利用 消息隊(duì)列 做一個(gè)通用的 “漏斗”,進(jìn)行 限流控制。在下游有能力處理的時(shí)候,再進(jìn)行分發(fā)。
3.2 具體場(chǎng)景
用戶在支付系統(tǒng)成功結(jié)賬后,訂單系統(tǒng)會(huì)通過(guò)短信系統(tǒng)向用戶推送扣費(fèi)通知。短信系統(tǒng) 可能由于 短板效應(yīng),速度卡在 網(wǎng)關(guān) 上(每秒幾百次請(qǐng)求),跟 前端的并發(fā)量 不是一個(gè)數(shù)量級(jí)。于是,就造成 支付系統(tǒng) 和 短信系統(tǒng) 的處理能力出現(xiàn)差異化。
然而用戶晚上個(gè)半分鐘左右收到短信,一般是不會(huì)有太大問題的。如果沒有消息隊(duì)列,兩個(gè)系統(tǒng)之間通過(guò) 協(xié)商、滑動(dòng)窗口 等復(fù)雜的方案也不是說(shuō)不能實(shí)現(xiàn)。但 系統(tǒng)復(fù)雜性 指數(shù)級(jí)增長(zhǎng),勢(shì)必在 上游 或者 下游 做 存儲(chǔ),并且要處理 定時(shí)、擁塞 等一系列問題。而且每當(dāng)有 處理能力有差距 的時(shí)候,都需要 單獨(dú) 開發(fā)一套邏輯來(lái)維護(hù)這套邏輯。
所以,利用中間系統(tǒng)轉(zhuǎn)儲(chǔ)兩個(gè)系統(tǒng)的通信內(nèi)容,并在下游系統(tǒng)有能力處理這些消息的時(shí)候,再處理這些消息,是一套相對(duì)較通用的方式。
應(yīng)用案例
(1)把消息隊(duì)列當(dāng)成可靠的 消息暫存地,進(jìn)行一定程度的 消息堆積;
(2)定時(shí)進(jìn)行消息投遞,比如模擬 用戶秒殺 訪問,進(jìn)行 系統(tǒng)性能壓測(cè)。

4. 消息驅(qū)動(dòng)的系統(tǒng)
具體場(chǎng)景
用戶新上傳了一批照片, 人臉識(shí)別系統(tǒng)需要對(duì)這個(gè)用戶的所有照片進(jìn)行聚類,聚類完成后由對(duì)賬系統(tǒng)重新生成用戶的人臉?biāo)饕?加快查詢)。這三個(gè)子系統(tǒng)間由消息隊(duì)列連接起來(lái),前一個(gè)階段的處理結(jié)果放入隊(duì)列中,后一個(gè)階段從隊(duì)列中獲取消息繼續(xù)處理。


該方法有如下優(yōu)點(diǎn):
(1)避免了直接調(diào)用下一個(gè)系統(tǒng)導(dǎo)致當(dāng)前系統(tǒng)失敗;
(2)每個(gè)子系統(tǒng)對(duì)于消息的處理方式可以更為靈活,可以選擇收到消息時(shí)就處理,可以選擇定時(shí)處理,也可以劃分時(shí)間段按不同處理速度處理;
5. 日志處理
將消息隊(duì)列用在 日志處理 中,比如 Kafka 的應(yīng)用,解決 海量日志 傳輸和緩沖的問題。
應(yīng)用案例
把日志進(jìn)行集中收集,用于計(jì)算 PV、用戶行為分析 等等。

6. 順序保證
在大多使用場(chǎng)景下,數(shù)據(jù)處理的順序都很重要。大部分消息隊(duì)列本來(lái)就是排序的,并且能保證數(shù)據(jù)會(huì)按照特定的順序來(lái)處理。
7. 消息通訊
消息隊(duì)列一般都內(nèi)置了 高效的通信機(jī)制,因此也可以用于單純的 消息通訊,比如實(shí)現(xiàn) 點(diǎn)對(duì)點(diǎn)消息隊(duì)列 或者 聊天室 等。
六、消息中間件常用協(xié)議
1. AMQP協(xié)議
AMQP即Advanced Message Queuing Protocol,一個(gè)提供統(tǒng)一消息服務(wù)的應(yīng)用層標(biāo)準(zhǔn)高級(jí)消息隊(duì)列協(xié)議,是應(yīng)用層協(xié)議的一個(gè)開放標(biāo)準(zhǔn),為面向消息的中間件設(shè)計(jì)?;诖藚f(xié)議的客戶端與消息中間件可傳遞消息,并不受客戶端/中間件不同產(chǎn)品,不同開發(fā)語(yǔ)言等條件的限制。
優(yōu)點(diǎn):可靠、通用
2. MQTT協(xié)議
MQTT(Message Queuing Telemetry Transport,消息隊(duì)列遙測(cè)傳輸)是IBM開發(fā)的一個(gè)即時(shí)通訊協(xié)議,有可能成為物聯(lián)網(wǎng)的重要組成部分。該協(xié)議支持所有平臺(tái),幾乎可以把所有聯(lián)網(wǎng)物品和外部連接起來(lái),被用來(lái)當(dāng)做傳感器和致動(dòng)器(比如通過(guò)Twitter讓房屋聯(lián)網(wǎng))的通信協(xié)議。
優(yōu)點(diǎn):格式簡(jiǎn)潔、占用帶寬小、移動(dòng)端通信、PUSH、嵌入式系統(tǒng)
3. STOMP協(xié)議
STOMP(Streaming Text Orientated Message Protocol)是流文本定向消息協(xié)議,是一種為MOM(Message Oriented Middleware,面向消息的中間件)設(shè)計(jì)的簡(jiǎn)單文本協(xié)議。STOMP提供一個(gè)可互操作的連接格式,允許客戶端與任意STOMP消息代理(Broker)進(jìn)行交互。
優(yōu)點(diǎn):命令模式(非topic\queue模式)
4. XMPP協(xié)議
XMPP(可擴(kuò)展消息處理現(xiàn)場(chǎng)協(xié)議,Extensible Messaging and Presence Protocol)是基于可擴(kuò)展標(biāo)記語(yǔ)言(XML)的協(xié)議,多用于即時(shí)消息(IM)以及在線現(xiàn)場(chǎng)探測(cè)。適用于服務(wù)器之間的準(zhǔn)即時(shí)操作。核心是基于XML流傳輸,這個(gè)協(xié)議可能最終允許因特網(wǎng)用戶向因特網(wǎng)上的其他任何人發(fā)送即時(shí)消息,即使其操作系統(tǒng)和瀏覽器不同。
優(yōu)點(diǎn):通用公開、兼容性強(qiáng)、可擴(kuò)展、安全性高,但XML編碼格式占用帶寬大
5. 其他基于TCP/IP自定義的協(xié)議
有些特殊框架(如:redis、kafka、zeroMq等)根據(jù)自身需要未嚴(yán)格遵循MQ規(guī)范,而是基于TCP\IP自行封裝了一套協(xié)議,通過(guò)網(wǎng)絡(luò)socket接口進(jìn)行傳輸,實(shí)現(xiàn)了MQ的功能。
七、常見消息中間件介紹與比較
1. 中間件介紹
1.1 ActiveMQ
簡(jiǎn)介
ActiveMQ 是由 Apache 出品,ActiveMQ 是一個(gè)完全支持JMS1.1 和 J2EE 1.4 規(guī)范的 JMS Provider 實(shí)現(xiàn)。它非??焖?,支持 多種語(yǔ)言的客戶端 和 協(xié)議,而且可以非常容易的嵌入到企業(yè)的應(yīng)用環(huán)境中,并有許多高級(jí)功能。
主要特性
(1)服從JMS規(guī)范:JMS 規(guī)范提供了良好的標(biāo)準(zhǔn)和保證,包括:同步 或 異步 的消息分發(fā),一次和僅一次的消息分發(fā),消息接收 和 訂閱 等等。遵從 JMS 規(guī)范的好處在于,不論使用什么 JMS 實(shí)現(xiàn)提供者,這些基礎(chǔ)特性都是可用的;
(2)連接靈活性:ActiveMQ 提供了廣泛的 連接協(xié)議,支持的協(xié)議有:HTTP/S,IP 多播,SSL,TCP,UDP 等等。對(duì)眾多協(xié)議的支持讓 ActiveMQ 擁有了很好的靈活性;
(3)支持的協(xié)議種類多:OpenWire、STOMP、REST、XMPP、AMQP;
(4)持久化插件和安全插件:ActiveMQ 提供了 多種持久化 選擇。而且,ActiveMQ 的安全性也可以完全依據(jù)用戶需求進(jìn)行 自定義鑒權(quán) 和 授權(quán);
(5)支持的客戶端語(yǔ)言種類多:除了 Java 之外,還有:C/C++,.NET,Perl,PHP,Python,Ruby;
(6)代理集群:多個(gè) ActiveMQ 代理 可以組成一個(gè) 集群 來(lái)提供服務(wù);
(7)異常簡(jiǎn)單的管理:ActiveMQ 是以開發(fā)者思維被設(shè)計(jì)的。所以,它并不需要專門的管理員,因?yàn)樗峁┝撕?jiǎn)單又使用的管理特性。有很多中方法可以 監(jiān)控 ActiveMQ 不同層面的數(shù)據(jù),包括使用在 JConsole 或者在 ActiveMQ 的 Web Console 中使用 JMX。通過(guò)處理 JMX 的告警消息,通過(guò)使用 命令行腳本,甚至可以通過(guò)監(jiān)控各種類型的 日志。
部署環(huán)境
ActiveMQ 可以運(yùn)行在 Java 語(yǔ)言所支持的平臺(tái)之上。使用 ActiveMQ 需要:
(1)Java JDK
(2)ActiveMQ 安裝包
優(yōu)點(diǎn)
(1)跨平臺(tái) (JAVA 編寫與平臺(tái)無(wú)關(guān),ActiveMQ 幾乎可以運(yùn)行在任何的 JVM 上);
(2)可以用 JDBC:可以將 數(shù)據(jù)持久化 到數(shù)據(jù)庫(kù)。雖然使用 JDBC 會(huì)降低 ActiveMQ 的性能,但是數(shù)據(jù)庫(kù)一直都是開發(fā)人員最熟悉的存儲(chǔ)介質(zhì);
(3)支持 JMS 規(guī)范:支持 JMS 規(guī)范提供的 統(tǒng)一接口;
(4)支持 自動(dòng)重連 和 錯(cuò)誤重試機(jī)制;
(5)有安全機(jī)制:支持基于 shiro,jaas 等多種 安全配置機(jī)制,可以對(duì) Queue/Topic 進(jìn)行 認(rèn)證和授權(quán);
(6)監(jiān)控完善:擁有完善的 監(jiān)控,包括 Web Console,JMX,Shell 命令行,Jolokia 的 RESTful API;
9)7界面友善:提供的 Web Console 可以滿足大部分情況,還有很多 第三方的組件 可以使用,比如 hawtio;
缺點(diǎn)
(1)社區(qū)活躍度不及 RabbitMQ 高;
(2)根據(jù)其他用戶反饋,會(huì)出莫名其妙的問題,會(huì) 丟失消息;
(3)目前重心放到 activemq 6.0 產(chǎn)品 Apollo,對(duì) 5.x 的維護(hù)較少;
(4)不適合用于 上千個(gè)隊(duì)列 的應(yīng)用場(chǎng)景;
1.2 RabbitMQ
RabbitMQ 于 2007 年發(fā)布,是一個(gè)在 AMQP (高級(jí)消息隊(duì)列協(xié)議)基礎(chǔ)上完成的,可復(fù)用的企業(yè)消息系統(tǒng),是當(dāng)前最主流的消息中間件之一。
主要特性
(1)可靠性:提供了多種技術(shù)可以讓你在 性能 和 可靠性 之間進(jìn)行 權(quán)衡。這些技術(shù)包括 持久性機(jī)制、投遞確認(rèn)、發(fā)布者證實(shí) 和 高可用性機(jī)制;
(2)靈活的路由:消息在到達(dá)隊(duì)列前是通過(guò) 交換機(jī) 進(jìn)行 路由 的。RabbitMQ 為典型的路由邏輯提供了 多種內(nèi)置交換機(jī) 類型。如果你有更復(fù)雜的路由需求,可以將這些交換機(jī)組合起來(lái)使用,你甚至可以實(shí)現(xiàn)自己的交換機(jī)類型,并且當(dāng)做 RabbitMQ 的 插件 來(lái)使用;
(3)消息集群:在相同局域網(wǎng)中的多個(gè) RabbitMQ 服務(wù)器可以 聚合 在一起,作為一個(gè)獨(dú)立的邏輯代理來(lái)使用;
(4)隊(duì)列高可用:隊(duì)列可以在集群中的機(jī)器上 進(jìn)行鏡像,以確保在硬件問題下還保證 消息安全;
(5)支持多種協(xié)議:支持 多種消息隊(duì)列協(xié)議;
(6)支持多種語(yǔ)言:用 Erlang 語(yǔ)言編寫,支持只要是你能想到的 所有編程語(yǔ)言;
(7)管理界面: RabbitMQ 有一個(gè)易用的 用戶界面,使得用戶可以 監(jiān)控 和 管理 消息 Broker 的許多方面;
(8)跟蹤機(jī)制:如果 消息異常,RabbitMQ 提供消息跟蹤機(jī)制,使用者可以找出發(fā)生了什么;
(9)插件機(jī)制:提供了許多 插件,來(lái)從多方面進(jìn)行擴(kuò)展,也可以編寫自己的插件。
部署環(huán)境
RabbitMQ 可以運(yùn)行在 Erlang 語(yǔ)言所支持的平臺(tái)之上,包括 Solaris,BSD,Linux,MacOSX,TRU64,Windows 等。使用 RabbitMQ 需要:
(1)ErLang 語(yǔ)言包
(2)RabbitMQ 安裝包
優(yōu)點(diǎn)
(1)由于 Erlang 語(yǔ)言的特性,消息隊(duì)列性能較好,支持 高并發(fā);
(2)健壯、穩(wěn)定、易用、跨平臺(tái)、支持 多種語(yǔ)言、文檔齊全;
(3)有消息 確認(rèn)機(jī)制 和 持久化機(jī)制,可靠性高;
(4)高度可定制的 路由;
(5)管理界面 較豐富,在互聯(lián)網(wǎng)公司也有較大規(guī)模的應(yīng)用,社區(qū)活躍度高。
缺點(diǎn)
(1)盡管結(jié)合 Erlang 語(yǔ)言本身的并發(fā)優(yōu)勢(shì),性能較好,但是不利于做 二次開發(fā)和維護(hù);
(2)實(shí)現(xiàn)了 代理架構(gòu),意味著消息在發(fā)送到客戶端之前可以在 中央節(jié)點(diǎn) 上排隊(duì)。此特性使得 RabbitMQ 易于使用和部署,但是使得其 運(yùn)行速度較慢,因?yàn)橹醒牍?jié)點(diǎn) 增加了延遲,消息封裝后 也比較大;
(3)需要學(xué)習(xí) 比較復(fù)雜 的 接口和協(xié)議,學(xué)習(xí)和維護(hù)成本較高。
1.3 RocketMQ
簡(jiǎn)介
RocketMQ 出自 阿里 的開源產(chǎn)品,用 Java 語(yǔ)言實(shí)現(xiàn),在設(shè)計(jì)時(shí)參考了 Kafka,并做出了自己的一些改進(jìn),消息可靠性上 比 Kafka 更好。RocketMQ 在阿里內(nèi)部被廣泛應(yīng)用在 訂單,交易,充值,流計(jì)算,消息推送,日志流式處理,binglog 分發(fā) 等場(chǎng)景。
主要特性

(1)基于 隊(duì)列模型:具有 高性能、高可靠、高實(shí)時(shí)、分布式 等特點(diǎn);
(2)Producer、Consumer、隊(duì)列 都支持 分布式;
(3)Producer 向一些隊(duì)列輪流發(fā)送消息,隊(duì)列集合 稱為 Topic。Consumer 如果做 廣播消費(fèi),則一個(gè) Consumer 實(shí)例消費(fèi)這個(gè) Topic 對(duì)應(yīng)的 所有隊(duì)列;如果做 集群消費(fèi),則 多個(gè) Consumer 實(shí)例 平均消費(fèi) 這個(gè) Topic 對(duì)應(yīng)的隊(duì)列集合;
(4)能夠保證 嚴(yán)格的消息順序;
(5)提供豐富的 消息拉取模式;
(6)高效的訂閱者 水平擴(kuò)展能力;
(7)實(shí)時(shí) 的 消息訂閱機(jī)制;
(8)億級(jí) 消息堆積 能力;
(9)較少的外部依賴。
部署環(huán)境
RocketMQ 可以運(yùn)行在 Java 語(yǔ)言所支持的平臺(tái)之上。使用 RocketMQ 需要:
(1)Java JDK
(2)安裝 git、Maven
(3)RocketMQ 安裝包
優(yōu)點(diǎn)
(1)單機(jī) 支持 1 萬(wàn)以上 持久化隊(duì)列;
(2)RocketMQ 的所有消息都是 持久化的,先寫入系統(tǒng) PAGECACHE,然后 刷盤,可以保證 內(nèi)存 與 磁盤 都有一份數(shù)據(jù),而 訪問 時(shí),直接 從內(nèi)存讀取。
(3)模型簡(jiǎn)單,接口易用(JMS 的接口很多場(chǎng)合并不太實(shí)用);
(4)性能非常好,可以允許 大量堆積消息 在 Broker 中;
(5)支持 多種消費(fèi)模式,包括 集群消費(fèi)、廣播消費(fèi)等;
(6)各個(gè)環(huán)節(jié) 分布式擴(kuò)展設(shè)計(jì),支持 主從 和 高可用;
(7)開發(fā)度較活躍,版本更新很快。
缺點(diǎn)
(1)支持的 客戶端語(yǔ)言 不多,目前是 Java 及 C++,其中 C++ 還不成熟;
(2)RocketMQ 社區(qū)關(guān)注度及成熟度也不及前兩者;
(3)沒有 Web 管理界面,提供了一個(gè) CLI (命令行界面) 管理工具帶來(lái) 查詢、管理 和 診斷各種問題;
(4)沒有在 MQ 核心里實(shí)現(xiàn) JMS 等接口;
1.4 Kafka
簡(jiǎn)介
Apache Kafka 是一個(gè) 分布式消息發(fā)布訂閱 系統(tǒng)。它最初由 LinkedIn 公司基于獨(dú)特的設(shè)計(jì)實(shí)現(xiàn)為一個(gè) 分布式的日志提交系統(tǒng) (a distributed commit log),之后成為 Apache 項(xiàng)目的一部分。Kafka 性能高效、可擴(kuò)展良好 并且 可持久化。它的 分區(qū)特性,可復(fù)制 和 可容錯(cuò) 都是其不錯(cuò)的特性。

主要特性
(1)快速持久化:可以在 O(1) 的系統(tǒng)開銷下進(jìn)行 消息持久化;
(2)高吞吐:在一臺(tái)普通的服務(wù)器上既可以達(dá)到 10W/s 的 吞吐速率;
(3)完全的分布式系統(tǒng):Broker、Producer 和 Consumer 都原生自動(dòng)支持 分布式,自動(dòng)實(shí)現(xiàn) 負(fù)載均衡;
(4)支持 同步 和 異步 復(fù)制兩種 高可用機(jī)制;
(5)支持 數(shù)據(jù)批量發(fā)送 和 拉??;
(6)零拷貝技術(shù)(zero-copy):減少 IO 操作步驟,提高 系統(tǒng)吞吐量;
(7)數(shù)據(jù)遷移、擴(kuò)容 對(duì)用戶透明;
(8)無(wú)需停機(jī) 即可擴(kuò)展機(jī)器;
(9)其他特性:豐富的 消息拉取模型、高效 訂閱者水平擴(kuò)展、實(shí)時(shí)的 消息訂閱、億級(jí)的 消息堆積能力、定期刪除機(jī)制;
部署環(huán)境
使用 Kafka 需要:
(1)Java JDK
(2)Kafka 安裝包
優(yōu)點(diǎn)
(1)客戶端語(yǔ)言豐富:支持 Java、.Net、PHP、Ruby、Python、Go 等多種語(yǔ)言;
(2)高性能:?jiǎn)螜C(jī)寫入 TPS 約在 100 萬(wàn)條/秒,消息大小 10 個(gè)字節(jié);
(3)提供 完全分布式架構(gòu),并有 replica 機(jī)制,擁有較高的 可用性 和 可靠性,理論上支持 消息無(wú)限堆積;
(4)支持批量操作;
(5)消費(fèi)者 采用 Pull 方式獲取消息。消息有序,通過(guò)控制 能夠保證所有消息被消費(fèi)且僅被消費(fèi) 一次;
(6)有優(yōu)秀的第三方 Kafka Web 管理界面 Kafka-Manager;
(7)在日志領(lǐng)域 比較成熟,被多家公司和多個(gè)開源項(xiàng)目使用。
缺點(diǎn)
(1)Kafka 單機(jī)超過(guò) 64 個(gè) 隊(duì)列/分區(qū) 時(shí),Load 時(shí)會(huì)發(fā)生明顯的飆高現(xiàn)象。隊(duì)列 越多,負(fù)載 越高,發(fā)送消息 響應(yīng)時(shí)間變長(zhǎng);
(2)使用 短輪詢方式,實(shí)時(shí)性 取決于 輪詢間隔時(shí)間;
(3)消費(fèi)失敗 不支持重試;
(4)支持 消息順序,但是 一臺(tái)代理宕機(jī) 后,就會(huì)產(chǎn)生 消息亂序;
(5)社區(qū)更新較慢。
2. 中間件比較
2.1 比較一
ZeroMq 最好,RabbitMq 次之, ActiveMq 最差。這個(gè)結(jié)論來(lái)自于以下這篇文章。
http://blog.x-aeon.com/2013/04/10/a-quick-message-queue-benchmark-activemq-rabbitmq-hornetq-qpid-apollo/
測(cè)試環(huán)境:
Model: Dell Studio 1749
CPU: Intel Core i3 @ 2.40 GH
RAM: 4 Gb
OS: Windows 7 64 bits
其中包括持久化消息和瞬時(shí)消息的測(cè)試。注意這篇文章里面提到的MQ,都是采用默認(rèn)配置的,并無(wú)調(diào)優(yōu)。


更多的統(tǒng)計(jì)圖請(qǐng)參看我提供的文章url。
2.2 比較二
ZeroMq 最好,RabbitMq次之, ActiveMq最差。這個(gè)結(jié)論來(lái)自于一下這篇文章。http://www.cnblogs.com/amityat/archive/2011/08/31/2160293.html
顯示的是發(fā)送和接受的每秒鐘的消息數(shù)。整個(gè)過(guò)程共產(chǎn)生1百萬(wàn)條1K的消息。測(cè)試的執(zhí)行是在一個(gè)Windows Vista上進(jìn)行的。

2.3 持久化消息比較
zeroMq不支持,activeMq和rabbitMq都支持。持久化消息主要是指:MQ down或者M(jìn)Q所在的服務(wù)器down了,消息不會(huì)丟失的機(jī)制。
2.4 技術(shù)點(diǎn):可靠性、靈活的路由、集群、事務(wù)、高可用的隊(duì)列、消息排序、問題追蹤、可視化管理工具、插件系統(tǒng)、社區(qū)
RabbitMq最好,ActiveMq次之,ZeroMq最差。當(dāng)然ZeroMq也可以做到,不過(guò)自己必須手動(dòng)寫代碼實(shí)現(xiàn),代碼量不小。尤其是可靠性中的:持久性、投遞確認(rèn)、發(fā)布者證實(shí)和高可用性。所以在可靠性和可用性上,RabbitMQ是首選,雖然ActiveMQ也具備,但是它性能不及RabbitMQ。
2.5 高并發(fā)
從實(shí)現(xiàn)語(yǔ)言來(lái)看,RabbitMQ最高,原因是它的實(shí)現(xiàn)語(yǔ)言是天生具備高并發(fā)高可用的erlang語(yǔ)言。
2.6 總體比較

結(jié)論:
(1)Kafka 在于 分布式架構(gòu),RabbitMQ 基于 AMQP 協(xié)議 來(lái)實(shí)現(xiàn),RocketMQ 的思路來(lái)源于 Kafka,改成了 主從結(jié)構(gòu),在 事務(wù)性 和 可靠性 方面做了優(yōu)化。廣泛來(lái)說(shuō),電商、金融 等對(duì) 事務(wù)一致性 要求很高的,可以考慮 RabbitMQ 和 RocketMQ,對(duì) 性能要求高 的可考慮 Kafka。
(2)按照目前網(wǎng)絡(luò)上的資料,RabbitMQ、activeMQ、zeroMQ三者中,綜合來(lái)看,RabbitMQ是首選,但是activeMQ與Java結(jié)合度比較好。