1. 程式人生 > >架構師基本功:訊息佇列

架構師基本功:訊息佇列

轉:http://blog.csdn.net/leftfist/article/details/50909175

訊息佇列是啥?我覺得大家都心知肚明,已經眾所周知到不用解釋的程度。不過,但凡學習、解釋一樣東西,都應該遵循
“它是什麼?”、
“做什麼用?”、
“為啥要用它”、
“它有啥分類”
這個套路,所以首先還是要給個定義。

世間無定義,老子只好自己給個定義:訊息佇列嘛,首先是個佇列,先進先出;然後,它傳遞訊息。。。

一、訊息佇列的作用
有高手總結為:
1、非同步處理
將不是必須的業務邏輯進行非同步處理,換言之,就是可以立即返回。

比如說,註冊,註冊資訊寫入資料庫以後,要發郵件,簡訊通知,如果等待這2樣都完成才返回,不管這2個步驟是序列還是並行,都要耗費時間。引入訊息佇列以後,註冊資訊寫入資料庫,隨即寫入訊息佇列,然後就可以返回了,後續工作由訊息佇列進行處理。假如除了發通知,還增加其他操作,比如加積分什麼的,這種方式優勢就更加明顯,業務主體完全不必修改,只需更改訊息佇列部分。
這裡寫圖片描述

2、應用解耦
兩個系統(或兩個模組)之間本來直接呼叫,現在是通過訊息佇列間接呼叫,類似事件觸發機制,這樣就將兩個系統或模組的關係由直接耦合變為鬆散耦合。
這裡寫圖片描述

3、流量削峰
這個比較容易理解,引入排隊機制。將併發變成了序列。假如訊息佇列長度超過最大數量,則直接拋棄使用者請求或跳轉到錯誤頁面。
這裡寫圖片描述

4、訊息通訊
既然是訊息佇列嘛,怎麼少得了發訊息?

5、日誌處理
我覺得這應該屬於 應用解耦 的範疇,為何單列出來?
這裡寫圖片描述

以下以JMS講述訊息服務及使用。JMS是java的訊息服務,其API是一個訊息服務的標準/規範。

二、訊息模型

1、點對點(P2P)模式
P2P模式包含三個角色:訊息佇列(Queue),傳送者(Sender),接收者(Receiver)。每個訊息都被髮送到一個特定的佇列,接收者從佇列中獲取訊息。佇列保留著訊息,直到他們被消費或超時。

P2P的特點:

1)每個訊息只有一個消費者,一旦被消費,訊息就不再在訊息佇列中。

2)傳送者和接收者之間在時間上沒有依賴性,也就是說當傳送者傳送了訊息之後,不管接收者有沒有正在執行,不會影響到訊息被髮送到佇列。

3)接收者在成功接收訊息之後需向佇列應答成功 。

如果希望傳送的每個訊息都會被成功處理的話,那麼需要P2P模式。

2、生產者/消費者(Pub/Sub)模式
包含三個角色主題(Topic),釋出者(Publisher),訂閱者(Subscriber) 多個釋出者將訊息傳送到Topic,系統將這些訊息傳遞給多個訂閱者。

Pub/Sub的特點:

1)每個訊息可以有多個消費者

2)釋出者和訂閱者之間有時間上的依賴性。針對某個主題(Topic)的訂閱者,它必須建立一個訂閱者之後,才能消費釋出者的訊息

3)為了消費訊息,訂閱者必須保持執行的狀態。或者建立一個可持久化的訂閱。這樣,即使訂閱者沒有被啟用(執行),它也能接收到釋出者的訊息。

如果希望傳送的訊息可以不被做任何處理、或者只被一個訊息者處理、或者可以被多個消費者處理的話,那麼可以採用Pub/Sub模型。

三、訊息消費
對於消費來說,有兩種方式:
1、同步
訂閱者或接收者在接收到訊息之前一直堵塞

2、非同步
訂閱者或接收者註冊一個訊息監聽器,訊息到達後,讀取訊息。

四、常用訊息佇列
一般商用的容器,如WebLogic,JBoss,都支援JMS標準,可以直接使用訊息佇列。但免費的如Tomcat,Jetty等則需要使用第三方的訊息中介軟體。
以下為一席常用的訊息中介軟體:
1、ActiveMQ
Apache出品。號稱最流行的,能力強勁的開源訊息匯流排。
特點有相容常見J2EE伺服器,支援Spring,Ajax

2、RabbitMQ
流行的、開源的訊息佇列。用AMQP(高階訊息佇列協議)標準實現。支援多種客戶端,包括.Net,Java,PHP。
用於分散式系統中儲存轉發訊息。易用性、擴充套件性、高可用性等方面表現不俗。

3、ZeroMQ
號稱史上最快的訊息佇列,實際類似於Socket的一系列介面。普通Socket是端到端(1:1)的關係,而ZMQ是N:M。ZMQ遮蔽了各種連線的細節,讓網路程式設計更簡單。
用於node與node間的通訊。node可以是主機或程序。

4、Kafka
高吞吐量的分散式釋出訂閱訊息系統。
持久化
高吞吐
叢集、分割槽
支援Hadoop

參考資料:
關於訊息佇列的使用這裡寫連結內容