1. 程式人生 > >訊息佇列中點對點模型與釋出/訂閱模式的區別

訊息佇列中點對點模型與釋出/訂閱模式的區別

背景知識

JMS一個在 Java標準化組織(JCP)內開發的標準(代號JSR 914)。2001年6月25日,Java訊息服務釋出JMS 1.0.2b,2002年3月18日Java訊息服務釋出 1.1. 
Java訊息服務(Java Message Service,JMS)應用程式介面是一個Java平臺中關於面向訊息中介軟體(MOM)的API,用於在兩個應用程式之間,或分散式系統中傳送訊息,進行非同步通訊。 
點對點與釋出訂閱最初是由JMS定義的。這兩種模式主要區別或解決的問題就是傳送到佇列的訊息能否重複消費(多訂閱)

1.JMS中定義

JMS規範目前支援兩種訊息模型:點對點(point to point, queue)和釋出/訂閱(publish/subscribe,topic)。 
點對點: 
訊息生產者生產訊息傳送到queue中,然後訊息消費者從queue中取出並且消費訊息。這裡要注意: 
訊息被消費以後,queue中不再有儲存,所以訊息消費者不可能消費到已經被消費的訊息。 
Queue支援存在多個消費者,但是對一個訊息而言,只會有一個消費者可以消費。 
釋出/訂閱 
訊息生產者(釋出)將訊息釋出到topic中,同時有多個訊息消費者(訂閱)消費該訊息。和點對點方式不同,釋出到topic的訊息會被所有訂閱者消費。

2.二者分析與區別

2.1 點對點模式

 
生產者傳送一條訊息到queue,只有一個消費者能收到。

2.2 釋出訂閱模式

 
釋出者傳送到topic的訊息,只有訂閱了topic的訂閱者才會收到訊息。

小結

queue實現了負載均衡,一個訊息只能被一個消費者接受,當沒有消費者可用時,這個訊息會被儲存直到有 一個可用的消費者,一個queue可以有很多消費者,他們之間實現了負載均衡, 
所以Queue實現了一個可靠的負載均衡。 
topic實現了釋出和訂閱,當你釋出一個訊息,所有訂閱這個topic的服務都能得到這個訊息,所以從1到N個訂閱者都能得到一個訊息的拷貝, 
只有在訊息代理收到訊息時有一個有效訂閱時的訂閱者才能得到這個訊息的拷貝。

疑問

釋出訂閱模式下,能否實現訂閱者負載均衡消費呢?當釋出者訊息量很大時,顯然單個訂閱者的處理能力是不足的。實際上現實場景中是多個訂閱者節點組成一個訂閱組負載均衡消費topic訊息即分組訂閱, 
這樣訂閱者很容易實現消費能力線性擴充套件。 

3 流行訊息佇列的訊息模型比較

傳統企業型訊息佇列ActiveMQ遵循了JMS規範,實現了點對點和釋出訂閱模型,但其他流行的訊息佇列RabbitMQ、Kafka並沒有遵循老態龍鍾的JMS規範,是通過什麼方式實現消費負載均衡、多訂閱呢?

3.1 RabbitMQ

RabbitMQ實現了AQMP協議,AQMP協議定義了訊息路由規則和方式。生產端通過路由規則傳送訊息到不同queue,消費端根據queue名稱消費訊息。此外RabbitMQ是向消費端推送訊息,訂閱關係和消費狀態儲存在服務端。 

 
生產端傳送一條訊息通過路由投遞到Queue,只有一個消費者能消費到。 
 
當RabbitMQ需要支援多訂閱時,釋出者傳送的訊息通過路由同時寫到多個Queue,不同訂閱組消費此訊息。 
RabbitMQ既支援記憶體佇列也支援持久化佇列,消費端為推模型,消費狀態和訂閱關係由服務端負責維護,訊息消費完後立即刪除,不保留歷史訊息。所以支援多訂閱時,訊息會多個拷貝。

3.2 Kafka

 
Kafka只支援訊息持久化,消費端為拉模型,消費狀態和訂閱關係由客戶端端負責維護,訊息消費完後不會立即刪除,會保留歷史訊息。因此支援多訂閱時,訊息只會儲存一份就可以了。