JMS與AMQP簡述以及比較
一、簡述
1.JMS(java message service)
由Sun公司早期提出的訊息標準,是一個Java平臺中關於面向訊息中介軟體(MOM)的API,旨在為java應用提供統一的訊息操作。
相關概念:
- 提供者:實現JMS規範的訊息中間伺服器
- 客戶端:傳送或接收訊息的應用程式
- 生產者/釋出者:建立併發送訊息的客戶端
- 消費者/訂閱者:接收並處理訊息的客戶端
- 訊息:應用程式之間傳遞的資料內容
JMS具有兩種通訊方式:
1.佇列(點對點)模式(Point to Point)
特點:
- 每個訊息只有一個消費者(Consumer)(即一旦被消費,訊息就不再在訊息佇列中);
- 傳送者和接收者之間在時間上沒有依賴性,也就是說當傳送者傳送了訊息之後,不管接收者有沒有正在執行,它不會影響到訊息被髮送到佇列;
- 接收者在成功接收訊息之後需向佇列應答成功。
2.主題模式模式(Publish/Subscribe)
特點:
- 一個訊息可以傳遞個多個訂閱者(即:一個訊息可以有多個接受方)
- 釋出者與訂閱者具有時間約束,針對某個主題(Topic)的訂閱者,它必須建立一個訂閱者之後,才能消費釋出者的訊息,而且為了消費訊息,訂閱者必須保持執行的狀態。
- 為了緩和這樣嚴格的時間相關性,JMS允許訂閱者建立一個可持久化的訂閱。這樣,即使訂閱者沒有被啟用(執行),它也能接收到釋出者的訊息。
注:ActiveMQ,HornetMQ是基於JMS實現的
2.AMQP(Advanced Message Queuing Protocol)
AMQP(advanced message queuing protocol)在2003年時被提出,最早用於解決金融領不同平臺之間的訊息傳遞互動問題。顧名思義,AMQP是一種協議,更準確的說是一種binary wire-level protocol(連結協議)。這是其和JMS的本質差別,AMQP不從API層進行限定,而是直接定義網路交換的資料格式。這使得實現了AMQP的provider天然性就是跨平臺的。意味著我們可以使用Java的AMQP provider,同時使用一個python的producer加一個rubby的consumer。從這一點看,AQMP可以用http來進行類比,不關心實現的語言,只要大家都按照相應的資料格式去傳送報文請求,不同語言的client均可以和不同語言的server連結。
相關概念:
- 訊息(Message):訊息是不具名的,它是有訊息頭和訊息體組成。訊息體是不透明的,而訊息頭是由一系列的可選屬性組成,這些屬性包括routing-key(路由鍵)、priority(權重)、delivery-mode(指出該訊息可能需要持久化儲存)等
- 訊息的生成者(Pulisher):也是一個想交換器釋出訊息的客戶端應用程式
- 交換器(Exchange):用來接收生產者傳送的訊息路由給伺服器中的佇列。它具有四種類型:direct(預設:點對點),fanout,topic,headers
- 訊息佇列(Queue):用來儲存訊息直到傳送給消費者。它是訊息的容器,也是訊息的終點。一個訊息可投入一個或者多個佇列、訊息一致在佇列裡面,等待消費者連線到這個佇列將其取走。
- 繫結(Binding):用於訊息佇列和交換器之間的關聯。一個繫結就是基於路由鍵將交換器和訊息佇列連線起來的路由規則,所以可以將路由器理解成一個由繫結構成的路由表。Exchange和Queue的繫結可以是多對多的關係。
- 網路連線(Connection):例如TCP連線。
- 通道(Channel):多路複用連線中的一條獨立的雙向庶幾乎流通道。通道是建立在真實的TCP連線內的虛擬連線,AMQP命令都是通過通道發出去的,不管是釋出訊息,訂閱佇列還是接收訊息也都是由通道完成的。因為對於作業系統來說建立和銷燬TCP都是非常昂貴的開銷,所以引入了通道的概念,以服用一條TCP連線。
- 訊息的消費者(Consumer):白哦是一個從訊息佇列中取得訊息的客戶端應用程式。
- 虛擬主機(Virtual Host):表示一批交換器、訊息佇列和相關的物件。虛擬主機是共享相同的身份認證和加密環境的獨立伺服器域。每個virtual host本質上就是一個mini半的RabbitMQ伺服器,擁有自己的佇列、交換器、繫結和許可權機制。virtual host 是AMQP概念的基礎,必須在連線時指定,Rabbit MQ預設的Virtual Host是/。
- 實體(Broker):表示訊息佇列伺服器實體。
Exchange四種類型:
1.Direct
單播,訊息中的路由鍵(routing-key) 如果和Binding中的binding key一致,交換器就發到對應的佇列中。
2.Fanout
廣播,每個發到fanout型別交換器的訊息都會分到所有繫結佇列上去。fanout交換器不處理路由鍵,只是簡單的將佇列繫結到交換器上,每個傳送到交換器的訊息都會被轉發到與該交換器繫結的所有佇列上。很像子網廣播,每臺子網內的主機都獲得了一份複製的訊息。fanout型別轉發訊息是最快的。
3.Topic
有選擇的廣播,topic交換器通過模式匹配分配訊息的路由鍵屬性,將路由鍵和某個模式進行匹配,此時佇列需要繫結到一個模式上。它將路由鍵和繫結鍵的字串分成單詞,這些單詞用點隔開(a.b)。它同樣也會識別兩個萬用字元:符號:# 匹配0或者多個單詞,*匹配一個單詞。
4.headers
不常用
注:RabbitMQ是基於AMQP實現的
二、對比
|
JMS |
AMQP |
定義 |
Java api |
Wire-protocol |
跨語言 |
否 |
是 |
跨平臺 |
否 |
是 |
Model |
提供兩種訊息模型: (1)、Peer-2-Peer (2)、Pub/sub |
提供了五種訊息模型: (1)、direct exchange (2)、fanout exchange (3)、topic change (4)、headers exchange (5)、system exchange 本質來講,後四種和JMS的pub/sub模型沒有太大差別,僅是在路由機制上做了更詳細的劃分; |
支援訊息型別 |
多種訊息型別: TextMessage MapMessage BytesMessage StreamMessage ObjectMessage Message (只有訊息頭和屬性) |
byte[] 當實際應用時,有複雜的訊息,可以將訊息序列化後傳送。 |
綜合評價 |
JMS 定義了JAVA API層面的標準;在java體系中,多個client均可以通過JMS進行互動,不需要應用修改程式碼,但是其對跨平臺的支援較差; |
AMQP定義了wire-level層的協議標準;天然具有跨平臺、跨語言特性。 |