消息隊列中間件是分佈式系統中重要的組件,主要解決應用解耦,異步消息,流量削鋒等問題,實現高性能,高可用,可伸縮和最終一致性架構。目前使用較多的消息隊列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ前端
如下介紹消息隊列在實際應用中經常使用的使用場景。異步處理,應用解耦,流量削鋒和消息通信四個場景。java
2.1異步處理 場景說明:用戶註冊後,須要發註冊郵件和註冊短信。傳統的作法有兩種 1.串行的方式;2.並行方式 a、串行方式:將註冊信息寫入數據庫成功後,發送註冊郵件,再發送註冊短信。以上三個任務所有完成後,返回給客戶端。數據庫
引入消息隊列,將不是必須的業務邏輯,異步處理。改造後的架構以下:服務器
2.2應用解耦 場景說明:用戶下單後,訂單系統須要通知庫存系統。傳統的作法是,訂單系統調用庫存系統的接口。以下圖:網絡
如何解決以上問題呢?引入應用消息隊列後的方案,以下圖:數據結構
2.3流量削鋒 流量削鋒也是消息隊列中的經常使用場景,通常在秒殺或團搶活動中使用普遍。 應用場景:秒殺活動,通常會由於流量過大,致使流量暴增,應用掛掉。爲解決這個問題,通常須要在應用前端加入消息隊列。 a、能夠控制活動的人數 b、能夠緩解短期內高流量壓垮應用架構
2.4日誌處理 日誌處理是指將消息隊列用在日誌處理中,好比Kafka的應用,解決大量日誌傳輸的問題。架構簡化以下併發
2.5消息通信 消息通信是指,消息隊列通常都內置了高效的通訊機制,所以也能夠用在純的消息通信。好比實現點對點消息隊列,或者聊天室等 點對點通信:負載均衡
聊天室通信:異步
以上實際是消息隊列的兩種消息模式,點對點或發佈訂閱模式。模型爲示意圖,供參考。
3.1電商系統
3.2日誌收集系統
4、JMS消息服務 講消息隊列就不得不提JMS 。JMS(JAVA Message Service,java消息服務)API是一個消息服務的標準/規範,容許應用程序組件基於JavaEE平臺建立、發送、接收和讀取消息。它使分佈式通訊耦合度更低,消息服務更加可靠以及異步性。 在EJB架構中,有消息bean能夠無縫的與JM消息服務集成。在J2EE架構模式中,有消息服務者模式,用於實現消息與應用直接的解耦。
4.1消息模型 在JMS標準中,有兩種消息模型P2P(Point to Point),Publish/Subscribe(Pub/Sub)。
4.1.1 P2P模式
P2P的特色 每一個消息只有一個消費者(Consumer)(即一旦被消費,消息就再也不在消息隊列中) 發送者和接收者之間在時間上沒有依賴性,也就是說當發送者發送了消息以後,無論接收者有沒有正在運行,它不會影響到消息被髮送到隊列 接收者在成功接收消息以後需向隊列應答成功 若是但願發送的每一個消息都會被成功處理的話,那麼須要P2P模式。
4.1.2 Pub/Sub模式
Pub/Sub的特色 每一個消息能夠有多個消費者 發佈者和訂閱者之間有時間上的依賴性。針對某個主題(Topic)的訂閱者,它必須建立一個訂閱者以後,才能消費發佈者的消息 爲了消費消息,訂閱者必須保持運行的狀態 爲了緩和這樣嚴格的時間相關性,JMS容許訂閱者建立一個可持久化的訂閱。這樣,即便訂閱者沒有被激活(運行),它也能接收到發佈者的消息。 若是但願發送的消息能夠不被作任何處理、或者只被一個消息者處理、或者能夠被多個消費者處理的話,那麼能夠採用Pub/Sub模型。
4.2消息消費 在JMS中,消息的產生和消費都是異步的。對於消費來講,JMS的消息者能夠經過兩種方式來消費消息。 (1)同步 訂閱者或接收者經過receive方法來接收消息,receive方法在接收到消息以前(或超時以前)將一直阻塞;
(2)異步 訂閱者或接收者能夠註冊爲一個消息監聽器。當消息到達以後,系統自動調用監聽器的onMessage方法。
JNDI:Java命名和目錄接口,是一種標準的Java命名系統接口。能夠在網絡上查找和訪問服務。經過指定一個資源名稱,該名稱對應於數據庫或命名服務中的一個記錄,同時返回資源鏈接創建所必須的信息。 JNDI在JMS中起到查找和訪問發送目標或消息來源的做用。
5、經常使用消息隊列
通常商用的容器,好比WebLogic,JBoss,都支持JMS標準,開發上很方便。但免費的好比Tomcat,Jetty等則須要使用第三方的消息中間件。本部份內容介紹經常使用的消息中間件(Active MQ,Rabbit MQ,Zero MQ,Kafka)以及他們的特色。
5.1 ActiveMQ ActiveMQ 是Apache出品,最流行的,能力強勁的開源消息總線。ActiveMQ 是一個徹底支持JMS1.1和J2EE 1.4規範的 JMS Provider實現,儘管JMS規範出臺已是好久的事情了,可是JMS在當今的J2EE應用中間仍然扮演着特殊的地位。
ActiveMQ特性以下: ⒈ 多種語言和協議編寫客戶端。語言: Java,C,C++,C#,Ruby,Perl,Python,PHP。應用協議: OpenWire,Stomp REST,WS Notification,XMPP,AMQP ⒉ 徹底支持JMS1.1和J2EE 1.4規範 (持久化,XA消息,事務) ⒊ 對Spring的支持,ActiveMQ能夠很容易內嵌到使用Spring的系統裏面去,並且也支持Spring2.0的特性 ⒋ 經過了常見J2EE服務器(如 Geronimo,JBoss 4,GlassFish,WebLogic)的測試,其中經過JCA 1.5 resource adaptors的配置,可讓ActiveMQ能夠自動的部署到任何兼容J2EE 1.4 商業服務器上 ⒌ 支持多種傳送協議:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA ⒍ 支持經過JDBC和journal提供高速的消息持久化 ⒎ 從設計上保證了高性能的集羣,客戶端-服務器,點對點 ⒏ 支持Ajax ⒐ 支持與Axis的整合 ⒑ 能夠很容易得調用內嵌JMS provider,進行測試
5.2 Kafka Kafka是一種高吞吐量的分佈式發佈訂閱消息系統,它能夠處理消費者規模的網站中的全部動做流數據。 這種動做(網頁瀏覽,搜索和其餘用戶的行動)是在現代網絡上的許多社會功能的一個關鍵因素。 這些數據一般是因爲吞吐量的要求而經過處理日誌和日誌聚合來解決。 對於像Hadoop的同樣的日誌數據和離線分析系統,但又要求實時處理的限制,這是一個可行的解決方案。Kafka的目的是經過Hadoop的並行加載機制來統一線上和離線的消息處理,也是爲了經過集羣機來提供實時的消費。
Kafka是一種高吞吐量的分佈式發佈訂閱消息系統,有以下特性: 經過O(1)的磁盤數據結構提供消息的持久化,這種結構對於即便數以TB的消息存儲也可以保持長時間的穩定性能。(文件追加的方式寫入數據,過時的數據按期刪除) 高吞吐量:即便是很是普通的硬件Kafka也能夠支持每秒數百萬的消息 支持經過Kafka服務器和消費機集羣來分區消息 支持Hadoop並行數據加載 Kafka相關概念 Broker Kafka集羣包含一個或多個服務器,這種服務器被稱爲broker[5] Topic 每條發佈到Kafka集羣的消息都有一個類別,這個類別被稱爲Topic。(物理上不一樣Topic的消息分開存儲,邏輯上一個Topic的消息雖然保存於一個或多個broker上但用戶只需指定消息的Topic便可生產或消費數據而沒必要關心數據存於何處) Partition Parition是物理上的概念,每一個Topic包含一個或多個Partition. Producer 負責發佈消息到Kafka broker Consumer 消息消費者,向Kafka broker讀取消息的客戶端。 Consumer Group 每一個Consumer屬於一個特定的Consumer Group(可爲每一個Consumer指定group name,若不指定group name則屬於默認的group)。 通常應用在大數據日誌處理或對實時性(少許延遲),可靠性(少許丟數據)要求稍低的場景使用。