MQ訊息中介軟體技術
AMQP,即Advanced Message Queuing Protocol,高階訊息佇列協議,是應用層協議的一個開放標準,為面向訊息的中介軟體設計。
AMQP的主要特徵是面向訊息、佇列、路由(包括點對點和釋出/訂閱)、可靠性、安全。
AMQP在訊息提供者和客戶端的行為進行了強制規定,使得不同賣商之間真正實現了互操作能力。
JMS是早期訊息中介軟體進行標準化的一個嘗試,它僅僅是在API級進行了規範,離建立互操作能力還差很遠。
與JMS不同,AMQP是一個Wire級的協議,它描述了在網路上傳輸的資料的格式,以位元組為流。因此任何遵守此資料格式的工具,其建立和解釋訊息,都能與其他相容工具進行互操作。
AMQP規範的版本:
0-8 是2006年6月釋出
0-9 於2006年12月釋出
0-9-1 於2008年11月釋出
0-10 於2009年下半年釋出
1.0 draft (文件還是草案)
AMQP的實現有:
1)OpenAMQ
AMQP的開源實現,用C語言編寫,運行於Linux、AIX、Solaris、Windows、OpenVMS。
2)Apache Qpid
Apache的開源專案,支援C++、Ruby、Java、JMS、Python和.NET。
3)Redhat Enterprise MRG
實現了AMQP的最新版本0-10,提供了豐富的特徵集,比如完全管理、聯合、Active-Active叢集,有Web控制檯,還有許多企業級特徵,客戶端支援C++、Ruby、Java、JMS、Python和.NET。
4)RabbitMQ
一個獨立的開源實現,伺服器端用Erlang語言編寫,支援多種客戶端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支援AJAX。RabbitMQ釋出在Ubuntu、FreeBSD平臺。
5)AMQP Infrastructure
Linux下,包括Broker、管理工具、Agent和客戶端。
6)ØMQ
一個高效能的訊息平臺,在分散式訊息網路可作為相容AMQP的Broker節點,綁定了多種語言,包括Python、C、C++、Lisp、Ruby等。
7)Zyre
是一個Broker,實現了RestMS協議和AMQP協議,提供了RESTful HTTP訪問網路AMQP的能力。
JMS協議介紹
JMS(Java Messaging Service)是Java平臺上有關面向訊息中介軟體的技術規範,它便於訊息系統中的Java應用程式進行訊息交換,並且通過提供標準的產生、傳送、接收訊息的介面簡化企業應用的開發。
JMS本身只定義了一系列的介面規範,是一種與廠商無關的 API,用來訪問訊息收發系統。它類似於 JDBC(Java Database Connectivity):這裡,JDBC 是可以用來訪問許多不同關係資料庫的 API,而 JMS 則提供同樣與廠商無關的訪問方法,以訪問訊息收發服務。許多廠商目前都支援 JMS,包括 IBM 的 MQSeries、BEA的 Weblogic JMS service和 Progress 的 SonicMQ,這只是幾個例子。 JMS 使您能夠通過訊息收發服務(有時稱為訊息中介程式或路由器)從一個 JMS 客戶機向另一個 JML 客戶機發送訊息。訊息是 JMS 中的一種型別物件,由兩部分組成:報頭和訊息主體。報頭由路由資訊以及有關該訊息的元資料組成。訊息主體則攜帶著應用程式的資料或有效負載。根據有效負載 的型別來劃分,可以將訊息分為幾種型別,它們分別攜帶:簡單文字 (TextMessage)、可序列化的物件 (ObjectMessage)、屬性集合 (MapMessage)、位元組流 (BytesMessage)、原始值流 (StreamMessage),還有無有效負載的訊息 (Message)。
STOMP協議介紹
STOMP,Streaming Text Orientated Message Protocol,是流文字定向訊息協議,是一種為MOM(Message Oriented Middleware,面向訊息的中介軟體)設計的簡單文字協議。
它提供了一個可互操作的連線格式,允許STOMP客戶端與任意STOMP訊息代理(Broker)進行互動,類似於OpenWire(一種二進位制協議)。
由於其設計簡單,很容易開發客戶端,因此在多種語言和多種平臺上得到廣泛應用。其中最流行的STOMP訊息代理是Apache ActiveMQ。
STOMP協議工作於TCP協議之上,使用了下列命令:
* SEND 傳送
* SUBSCRIBE 訂閱
* UNSUBSCRIBE 退訂
* BEGIN 開始
* COMMIT 提交
* ABORT 取消
* ACK 確認
* DISCONNECT 斷開
訊息中介軟體概況
訊息佇列技術是分散式應用間交換資訊的一種技術。訊息佇列可駐留在記憶體或磁碟上,佇列儲存訊息直到它們被應用程式讀走。通過訊息佇列,應用程式可獨立地執行–它們不需要知道彼此的位置、或在繼續執行前不需要等待接收程式接收此訊息。
在分散式計算環境中,為了整合分散式應用,開發者需要對異構網路環境下的分散式應用提供有效的通訊手段。為了管理需要共享的資訊,對應用提供公共的資訊交換機制是重要的。
設計分散式應用的方法主要有:遠端過程呼叫(PRC)-分散式計算環境(DCE)的基礎標準成分之一;物件事務監控(OTM)-基於CORBA的面向物件工業標準與事務處理(TP)監控技術的組合;訊息佇列(MessageQueue)-構造分散式應用的鬆耦合方法。
(a) 分佈計算環境/遠端過程呼叫 (DCE/RPC)
RPC是DCE的成分,是一個由開放軟體基金會(OSF)釋出的應用整合的軟體標準。RPC模仿一個程式用函式引用來引用另一程式的傳統程式設計方法,此引用是過程呼叫的形式,一旦被呼叫,程式的控制則轉向被呼叫程式。
在RPC 實現時,被呼叫過程可在本地或遠地的另一系統中駐留並在執行。當被呼叫程式完成處理輸入資料,結果放在過程呼叫的返回變數中返回到呼叫程式。RPC完成後程式控制則立即返回到呼叫程式。因此RPC模仿子程式的呼叫/返回結構,它僅提供了Client(呼叫程式)和Server(被呼叫過程)間的同步資料交換。
(b) 物件事務監控 (OTM)
基於CORBA的面向物件工業標準與事務處理(TP)監控技術的組合,在CORBA規範中定義了:使用面向物件技術和方法的體系結構;公共的 Client/Server程式設計介面;多平臺間傳輸和翻譯資料的指導方針;開發分散式應用介面的語言(IDL)等,併為構造分佈的 Client/Server應用提供了廣泛及一致的模式。
(c) 訊息佇列 (Message Queue)
訊息佇列為構造以同步或非同步方式實現的分散式應用提供了鬆耦合方法。訊息佇列的API呼叫被嵌入到新的或現存的應用中,通過訊息傳送到記憶體或基於磁碟的佇列或從它讀出而提供資訊交換。訊息佇列可用在應用中以執行多種功能,比如要求服務、交換資訊或非同步處理等。
中介軟體是一種獨立的系統軟體或服務程式,分散式應用系統藉助這種軟體在不同的技術之間共享資源,管理計算資源和網路通訊。它在計算機系統中是一個關鍵軟體,它能實現應用的互連和互操作性,能保證系統的安全、可靠、高效的執行。中介軟體位於使用者應用和作業系統及網路軟體之間,它為應用提供了公用的通訊手段,並且獨立於網路和作業系統。中介軟體為開發者提供了公用於所有環境的應用程式介面,當應用程式中嵌入其函式呼叫,它便可利用其執行的特定作業系統和網路環境的功能,為應用執行通訊功能。
如果沒有訊息中介軟體完成資訊交換,應用開發者為了傳輸資料,必須要學會如何用網路和作業系統軟體的功能,編寫相應的應用程式來發送和接收資訊,且交換資訊沒有標準方法,每個應用必須進行特定的程式設計從而和多平臺、不同環境下的一個或多個應用通訊。例如,為了實現網路上不同主機系統間的通訊,將要求具備在網路上如何交換資訊的知識(比如用TCP/IP的socket程式設計);為了實現同一主機內不同程序之間的通訊,將要求具備作業系統的訊息佇列或命名管道(Pipes)等知識。
目前中介軟體的種類很多,如交易管理中介軟體、面向Java應用的Web應用伺服器中介軟體等,而訊息傳輸中介軟體(MOM)是其中的一種。它簡化了應用之間資料的傳輸,遮蔽底層異構作業系統和網路平臺,提供一致的通訊標準和應用開發,確保分散式計算網路環境下可靠的、跨平臺的資訊傳輸和資料交換。它基於訊息佇列的儲存-轉發機制,並提供特有的非同步傳輸機制,能夠基於訊息傳輸和非同步事務處理實現應用整合與資料交換。
釋出-訂閱訊息模式
一、 訂閱雜誌
我們很多人都訂過雜誌,其過程很簡單。只要告訴郵局我們所要訂的雜誌名、投遞的地址,付了錢就OK。出版社定期會將出版的雜誌交給郵局,郵局會根據訂閱的列表,將雜誌送達消費者手中。這樣我們就可以看到每一期精彩的雜誌了。
仔細思考一下訂雜誌的過程,我們會發現這樣幾個特點:1、 消費者訂雜誌不需要直接找出版社;2、 出版社只需要把雜誌交給郵局;3、 郵局將雜誌送達消費者。郵局在整個過程中扮演了非常重要的中轉作用,在出版社和消費者相互不需要知道對方的情況下,郵局完成了雜誌的投遞。
二、 釋出-訂閱訊息模式
剛剛講了訂閱雜誌,下面我們會講傳統呼叫模式演化到釋出-訂閱訊息模式。
有些網站在註冊使用者成功後發一封啟用郵件,使用者收到郵件後點擊啟用連結後才能使用該網站。一般的做法是在註冊使用者業務邏輯中呼叫傳送郵件的邏輯。這 樣使用者業務就依賴於郵件業務。如果以後改為簡訊啟用,註冊使用者業務邏輯就必須修改為呼叫傳送簡訊的邏輯。如果要註冊後給使用者加點積分,再加一段邏輯。經過 多次修改,我們發現很簡單的註冊使用者業務已經越來越複雜,越來越難以維護。相信很多開發者都會有類似痛苦的經歷。
即使使用者業務實現中對其他業務是介面依賴,也避免不了業務變化帶來的依賴影響。怎麼辦?解耦!將註冊使用者業務邏輯中註冊成功後的處理剝離出來。
再回頭看看”訂閱雜誌”,如果沒有郵局,出版社就必須自己將雜誌送達所有消費者。這種情形就和現在的註冊使用者業務一樣。我們發現問題了,在使用者業務和其他業務之間缺少了郵局所扮角色。
我們把郵局抽象成一個管理訊息的地方,叫”訊息管理器”。註冊使用者成功後傳送一個訊息給訊息管理器,由訊息管理器轉發該訊息給需要處理的業務。現在,使用者業務只依賴於訊息管理器了,它再也不會為了註冊使用者成功後的其他處理而煩惱。
註冊使用者的改造就是借鑑了”訂閱雜誌”這樣原始的模式。我們再進一步抽象,使用者業務就是訊息的”生產者”,它將訊息釋出到訊息管理器。郵件業務就是 訊息的”消費者”,它將收到的訊息進行處理。郵局可以訂閱很多種雜誌,雜誌都是通過某種編號來區分;訊息管理器也可以管理多種訊息,每種訊息都會有一個 “主題”來區分,消費者都是通過主題來訂閱的。
釋出-訂閱訊息模式已經呈現在我們面前,利用它可以產生更靈活、更鬆散耦合的系統。
MQ相關概念
1.訊息(Message)
訊息是MQ中最小的概念,本質上就是一段資料,它能被一個或者多個應用程式所理解,是應用程式之間傳遞的資訊載體。
2.佇列(Queue)
2.1本地佇列
本地佇列按照功能可劃分為初始化佇列,傳輸佇列,目標佇列和死信佇列。
初始化佇列用作訊息觸發功能。
傳輸佇列只是暫存待傳的訊息,條件許可的情況下,通過管道將訊息傳送到其他的佇列管理器。
目標佇列是訊息的目的地,可以長期存放訊息。
如果訊息不能送達目標佇列,也不能再路由出去,則被自動放入死信佇列儲存。
2.2別名佇列&遠端佇列
只是一個佇列定義,用來指定遠端佇列管理器的佇列。使用了遠端佇列,程式就不需要知道目標佇列的位置。
2.3模型佇列
模型佇列定義了一套本地佇列的屬性結合,一旦開啟模型佇列,佇列管理器會按照這些屬性動態地創建出一個本地佇列。
3.佇列管理器(Queue Manager)
佇列管理器是一個負責嚮應用程式提供訊息服務的機構,如果把佇列管理器比作資料庫,那麼佇列就是其中一張表。
4.通道(Channel)
通道是兩個管理器之間的一種單向點對點的的通訊連線,如果需要雙向交流,可以建立一對通道。
5.監聽器(listner)
MQ產品的特性
可靠性傳輸
這個特點可以說是訊息中介軟體的立足之本,對於應用來說,只要成功把資料提交給訊息中介軟體,那麼關於資料可靠傳輸的問題就由訊息中介軟體來負責。
不重複傳輸
不重複傳播也就是斷點續傳的功能,特別適合網路不穩定的環境,節約網路資源。
非同步性傳輸
非同步性傳輸是指,接受資訊雙方不必同時線上,具有離線能力和安全性。
訊息驅動
接到訊息後主動通知訊息接收方。
支援事務
應用程式可以把一些資料更新組合成一個工作單元,這些更新通常是邏輯相關的,為了保障資料完整性,所有的更新必須同時成功或者同時失敗)。
常用MQ產品比較
ActiveMQ | Joram | HornetQ | OpenMQ | MuleMQ | SonicMQ | RabbitMQ | ZeroMQ | |
關注度 | 高 | 中 | 中 | 中 | 低 | 低 | 高 | 中 |
成熟度 | 成熟 | 比較成熟 | 比較成熟 | 比較成熟 | 新產品無成功案例 | 成熟 | 成熟 | 不成熟 |
所屬社群/公司 | Apache | OW2 | Jboss | Sun | Mule | Progress | ||
社群活躍度 | 高 | 中 | 中 | 低 | 高 | 低 | 高 | 低 |
文件 | 多 | 多 | 中 | 中 | 少 | 少 | 多 | 中 |
特點 | 功能齊全,被大量開源專案使用 | 在Linux平臺上直接呼叫作業系統的AIO,效能得到很大的提升 | 效能非常好,與MuleESB無縫整合 | 效能優越的商業MQ | 由於Erlang語言的併發能力,效能很好 | 低延時,高效能,最高43萬條訊息每秒 | ||
授權方式 | 開源 | 開源 | 開源 | 開源 | 商業 | 商業 | 開源 | 開源 |
開發語言 | Java | Java | Java | Java | Java | Java | Erlang | C |
支援的協議 | OpenWire、STOMP、REST、XMPP、AMQP | JMS | JMS | JMS | JMS | JMS | AMQP | TCP、UDP |
客戶端支援語言 | Java、C、C++、Python、PHP、Perl、.net等 | Java | Java | Java | Java | Java、C、C++、.net | Java、C、C++、Python、PHP、Perl等 | python、java、php、.net等 |
持久化 | 記憶體、檔案、資料庫 | 記憶體、檔案 | 記憶體、檔案 | 記憶體、檔案 | 記憶體、檔案 | 記憶體、檔案、資料庫 | 記憶體、檔案 | 在訊息傳送端儲存 |
事務 | 支援 | 支援 | 支援 | 支援 | 支援 | 支援 | 不支援 | 不支援 |
叢集 | 支援 | 支援 | 支援 | 支援 | 支援 | 支援 | 支援 | 不支援 |
負載均衡 | 支援 | 支援 | 支援 | 支援 | 支援 | 支援 | 支援 | 不支援 |
管理介面 | 一般 | 一般 | 無 | 一般 | 一般 | 好 | 無 | 無 |
部署方式 | 獨立、嵌入 | 獨立、嵌入 | 獨立、嵌入 | 獨立、嵌入 | 獨立 | 獨立 | 獨立 | 獨立 |
評價 | 成熟穩定,開源首選 | 依賴容器,不適合跨語言呼叫 | 推出的時間不長,尚無使用案例,不適合跨語言呼叫 | 依賴容器,不適合跨語言呼叫 | 推出的時間不長,無成功案例,目前僅支援Java | 成熟穩定 | Queue的數量大於50後,高併發下無法持續穩定的提供服務 | 不支援事務、叢集,並且訊息不能在服務端持久化 |
MQ適用場景介紹
MQ訊息佇列是應運鬆偶合的概念而產生的,主要以佇列和釋出訂閱為訊息傳輸機制,以非同步的方式將訊息可靠的傳輸到消費端的一種基礎產品。
它被廣泛的應用與跨平臺、跨系統的分散式系統之間,為它們提供高效可靠的非同步傳輸機制。
-
訊息通道(Message Channel)
使用MQ將彼此協作的客戶端和服務端連線起來,使他們可以交換訊息。
如客戶端與服務端需要安全可靠的互動,可以將一個MQ的佇列作為安全通道,是客戶端與服務端能夠安全高效的進行非同步通訊。
-
訊息匯流排(Message Bus)
對於由許多獨立開發的服務組成的分散式系統,倘若要將它們組成一個完整的系統,這些服務必須能夠可靠地互動,同時,為了系統的健壯性,
每個服務之間又不能產生過分緊密的依賴關係,這樣就可以通過訊息匯流排將不同的服務連線起來,允許它們非同步的傳遞資料。
-
訊息路由(Message Router)
通過訊息路由,可以將傳送到MQ指定佇列的訊息根據規則路由到不同的佇列。
此外,JMS規範還支援通過selector條件,對訊息進行過濾,可以用多個消費者消費同一個佇列的訊息,每個消費者只消費自己感興趣的訊息。
-
釋出/訂閱(Publicsher/Subscriber)
釋出/訂閱模式用於一對多的通訊,當訊息釋出者向一個主題(Topic)傳送一條訊息後,該主題的所有訂閱者都會收到這條訊息。
來源: https://my.oschina.net/sundasheng44/blog/839178