【第二篇的內容大部分為網(wǎng)絡資源的整理和匯總,供大家學習總結使用,最后有文章來源】本次分享大綱(接上篇)消息隊列概述(見第一篇:大型網(wǎng)站架構系列:分布式消息隊列(一)) 消息隊列應用場景(見第一篇:大型網(wǎng)站架構系列:分布式消息隊列(一)) 消息中間件示例(見第一篇:大型網(wǎng)站架構系列:分布式消息隊列(一)) JMS消息服務 常用消息隊列 參考(推薦)資料 本次分享總結
四、JMS消息服務講消息隊列就不得不提JMS 。 JMS(JAVA Message Service,java消息服務)API是一個消息服務的標準/規(guī)范,允許應用程序組件基于JavaEE平臺創(chuàng)建、發(fā)送、接收和讀取消息。它使分布式通信耦合度更低,消息服務更加可靠以及異步性。 在EJB架構中,有消息bean可以無縫的與JM消息服務集成。在J2EE架構模式中,有消息服務者模式,用于實現(xiàn)消息與應用直接的解耦。 4.1消息模型在JMS標準中,有兩種消息模型P2P (Point to Point ),Publish /Subscribe (Pub/Sub )。 4.1.1 P2P模式
P2P模式包含三個角色: 消息隊列(Queue ) 發(fā)送者(Sender ) 接收者(Receiver )
每個消息都被發(fā)送到一個特定的隊列,接收者從隊列中獲取消息。隊列保留著消息,直到他們被消費或超時。 P2P的特點: 如果希望發(fā)送的每個消息都會被成功處理的話,那么需要P2P模式。 4.1.2 Pub/sub模式 包含三個角色: 主題(Topic ) 發(fā)布者(Publisher ) 訂閱者(Subscriber )
多個發(fā)布者將消息發(fā)送到Topic ,系統(tǒng)將這些消息傳遞給多個訂閱者。 Pub/Sub的特點 為了緩和這樣嚴格的時間相關性,JMS 允許訂閱者創(chuàng)建一個可持久化的訂閱。這樣,即使訂閱者沒有被激活(運行),它也能接收到發(fā)布者的消息。 如果希望發(fā)送的消息可以不被做任何處理、或者只被一個消息者處理、或者可以被多個消費者處理的話,那么可以采用Pub/Sub 模型。 4.2消息消費在JMS 中,消息的產生和消費都是異步的。對于消費來說,JMS 的消息者可以通過兩種方式來消費消息。 (1)同步 訂閱者或接收者通過receive 方法來接收消息,receive 方法在接收到消息之前(或超時之前)將一直阻塞; (2)異步 訂閱者或接收者可以注冊為一個消息監(jiān)聽器。當消息到達之后,系統(tǒng)自動調用監(jiān)聽器的onMessage 方法。 JNDI :Java 命名和目錄接口,是一種標準的Java命名系統(tǒng)接口。可以在網(wǎng)絡上查找和訪問服務。通過指定一個資源名稱,該名稱對應于數(shù)據(jù)庫或命名服務中的一個記錄,同時返回資源連接建立所必須的信息。
JNDI 在JMS 中起到查找和訪問發(fā)送目標或消息來源的作用。
4.3JMS編程模型(1) ConnectionFactory 創(chuàng)建Connection 對象的工廠,針對兩種不同的jms 消息模型,分別有QueueConnectionFactory 和TopicConnectionFactory 兩種??梢酝ㄟ^JNDI 來查找ConnectionFactory 對象。 (2) Destination
Destination 的意思是消息生產者的消息發(fā)送目標或者說消息消費者的消息來源。對于消息生產者來說,它的Destination 是某個隊列(Queue )或某個主題(Topic );對于消息消費者來說,它的`Destination 也是某個隊列或主題(即消息來源)。 所以,Destination 實際上就是兩種類型的對象:Queue 、Topic 可以通過JNDI 來查找Destination 。 (3) Connection
Connection 表示在客戶端和JMS系統(tǒng)之間建立的鏈接(對TCP/IP socket 的包裝)。Connection 可以產生一個或多個Session 。跟ConnectionFactory 一樣,Connection 也有兩種類型:QueueConnection 和TopicConnection 。 (4) Session
Session 是操作消息的接口??梢酝ㄟ^session 創(chuàng)建生產者、消費者、消息等。Session 提供了事務的功能。當需要使用session 發(fā)送/接收多個消息時,可以將這些發(fā)送/接收動作放到一個事務中。同樣,也分QueueSession 和TopicSession 。 (5) 消息的生產者 消息生產者由Session 創(chuàng)建,并用于將消息發(fā)送到Destination 。同樣,消息生產者分兩種類型:QueueSender 和TopicPublisher ??梢哉{用消息生產者的方法(send 或publish 方法)發(fā)送消息。 (6) 消息消費者 消息消費者由Session 創(chuàng)建,用于接收被發(fā)送到Destination 的消息。兩種類型:QueueReceiver 和TopicSubscriber ??煞謩e通過session 的createReceiver (Queue )或createSubscriber (Topic )來創(chuàng)建。當然,也可以session 的creatDurableSubscriber 方法來創(chuàng)建持久化的訂閱者。 (7) MessageListener 消息監(jiān)聽器。如果注冊了消息監(jiān)聽器,一旦消息到達,將自動調用監(jiān)聽器的onMessage 方法。EJB中的MDB(Message-Driven Bean )就是一種MessageListener 。 深入學習JMS 對掌握JAVA 架構,EJB 架構有很好的幫助,消息中間件也是大型分布式系統(tǒng)必須的組件。本次分享主要做全局性介紹,具體的深入需要大家學習,實踐,總結,領會。 五、常用消息隊列一般商用的容器,比如WebLogic ,JBoss ,都支持JMS 標準,開發(fā)上很方便。但免費的比如Tomcat ,Jetty 等則需要使用第三方的消息中間件。 本部分內容介紹常用的消息中間件(Active MQ ,Rabbit MQ ,Zero MQ ,Kafka )以及他們的特點。 5.1 ActiveMQActiveMQ 是Apache 出品,最流行的,能力強勁的開源消息總線。ActiveMQ 是一個完全支持JMS1.1 和J2EE 1.4 規(guī)范的 JMS Provider 實現(xiàn),盡管JMS 規(guī)范出臺已經是很久的事情了,但是JMS 在當今的J2EE 應用中間仍然扮演著特殊的地位。
ActiveMQ特性如下: 多種語言和協(xié)議編寫客戶端。語言: Java ,C ,C++ ,C# ,Ruby ,Perl ,Python ,PHP 。應用協(xié)議: OpenWire ,Stomp REST ,WS Notification ,XMPP ,AMQP 完全支持JMS1.1 和J2EE 1.4 規(guī)范 (持久化,XA消息,事務) 對Spring 的支持,ActiveMQ 可以很容易內嵌到使用Spring 的系統(tǒng)里面去,而且也支持Spring2.0 的特性 通過了常見J2EE服務器(如 Geronimo ,JBoss 4 ,GlassFish ,WebLogic )的測試,其中通過JCA 1.5 resource adaptors 的配置,可以讓ActiveMQ 可以自動的部署到任何兼容J2EE 1.4 商業(yè)服務器上 支持多種傳送協(xié)議:in-VM ,TCP ,SSL ,NIO ,UDP ,JGroups ,JXTA 支持通過JDBC 和journal 提供高速的消息持久化 從設計上保證了高性能的集群,客戶端-服務器,點對點 支持Ajax 支持與Axis 的整合 可以很容易得調用內嵌JMS provider ,進行測試
5.2 RabbitMQRabbitMQ 是流行的開源消息隊列系統(tǒng),用erlang 語言開發(fā)。
RabbitMQ 是AMQP (高級消息隊列協(xié)議)的標準實現(xiàn)。
支持多種客戶端,如:Pytho 、Ruby 、.NET 、Java 、JMS 、C 、PHP 、ActionScript 、XMPP 、STOMP 等,支持AJAX ,持久化。 用于在分布式系統(tǒng)中存儲轉發(fā)消息,在易用性、擴展性、高可用性等方面表現(xiàn)不俗。 結構圖如下: 幾個重要概念: Broker :簡單來說就是消息隊列服務器實體。
Exchange :消息交換機,它指定消息按什么規(guī)則,路由到哪個隊列。
Queue :消息隊列載體,每個消息都會被投入到一個或多個隊列。
Binding :綁定,它的作用就是把exchange和queue按照路由規(guī)則綁定起來。
Routing Key :路由關鍵字,exchange根據(jù)這個關鍵字進行消息投遞。
vhost :虛擬主機,一個broker里可以開設多個vhost,用作不同用戶的權限分離。
producer :消息生產者,就是投遞消息的程序。
consumer :消息消費者,就是接受消息的程序。
channel :消息通道,在客戶端的每個連接里,可建立多個channel,每個channel代表一個會話任務。
消息隊列的使用過程,如下: 客戶端連接到消息隊列服務器,打開一個channel 。 客戶端聲明一個exchange ,并設置相關屬性。 客戶端聲明一個queue ,并設置相關屬性。 客戶端使用routing key ,在exchange 和queue 之間建立好綁定關系。 客戶端投遞消息到exchange 。
exchange 接收到消息后,就根據(jù)消息的key和已經設置的binding,進行消息路由,將消息投遞到一個或多個隊列里。
5.3 ZeroMQ號稱史上最快的消息隊列,它實際類似于Socket 的一系列接口,他跟Socket 的區(qū)別是:普通的socket 是端到端的(1:1 的關系),而ZMQ 卻是可以N:M 的關系. 人們對BSD 套接字的了解較多的是點對點的連接,點對點連接需要顯式地建立連接、銷毀連接、選擇協(xié)議(TCP/UDP)和處理錯誤等,而ZMQ 屏蔽了這些細節(jié),讓你的網(wǎng)絡編程更為簡單。 ZMQ 用于node 與node 間的通信,node 可以是主機或者是進程。
引用官方的說法: “ZMQ(以下ZeroMQ簡稱ZMQ)是一個簡單好用的傳輸層,像框架一樣的一個socket library ,他使得Socket 編程更加簡單、簡潔和性能更高。是一個消息處理隊列庫,可在多個線程、內核和主機盒之間彈性伸縮。 ZMQ 的明確目標是“成為標準網(wǎng)絡協(xié)議棧的一部分,之后進入Linux內核”。
現(xiàn)在還未看到它們的成功。但是,它無疑是極具前景的、并且是人們更加需要的“傳統(tǒng)”BSD 套接字之上的一 層封裝。ZMQ 讓編寫高性能網(wǎng)絡應用程序極為簡單和有趣。 特點是: 與RabbitMQ 相比,ZMQ 并不像是一個傳統(tǒng)意義上的消息隊列服務器,事實上,它也根本不是一個服務器,更像一個底層的網(wǎng)絡通訊庫,在Socket API 之上做了一層封裝,將網(wǎng)絡通訊、進程通訊和線程通訊抽象為統(tǒng)一的API 接口。 支持“Request-Reply “,”Publisher-Subscriber “,”Parallel Pipeline ”三種基本模型和擴展模型。 ZeroMQ高性能設計要點: 1、無鎖的隊列模型 對于跨線程間的交互(用戶端和session )之間的數(shù)據(jù)交換通道pipe ,采用無鎖的隊列算法CAS ;在pipe 兩端注冊有異步事件,在讀或者寫消息到pipe 的時,會自動觸發(fā)讀寫事件。 2、批量處理的算法 對于傳統(tǒng)的消息處理,每個消息在發(fā)送和接收的時候,都需要系統(tǒng)的調用,這樣對于大量的消息,系統(tǒng)的開銷比較大,zeroMQ 對于批量的消息,進行了適應性的優(yōu)化,可以批量的接收和發(fā)送消息。 3、多核下的線程綁定,無須CPU切換 區(qū)別于傳統(tǒng)的多線程并發(fā)模式,信號量或者臨界區(qū), zeroMQ 充分利用多核的優(yōu)勢,每個核綁定運行一個工作者線程,避免多線程之間的CPU切換開銷。 5.4 KafkaKafka 是一種高吞吐量的分布式發(fā)布訂閱消息系統(tǒng),它可以處理消費者規(guī)模的網(wǎng)站中的所有動作流數(shù)據(jù)。 這種動作(網(wǎng)頁瀏覽,搜索和其他用戶的行動)是在現(xiàn)代網(wǎng)絡上的許多社會功能的一個關鍵因素。
這些數(shù)據(jù)通常是由于吞吐量的要求而通過處理日志和日志聚合來解決。 對于像Hadoop 的一樣的日志數(shù)據(jù)和離線分析系統(tǒng),但又要求實時處理的限制,這是一個可行的解決方案。 Kafka 的目的是通過Hadoop 的并行加載機制來統(tǒng)一線上和離線的消息處理,也是為了通過集群機來提供實時的消費。
Kafka 是一種高吞吐量的分布式發(fā)布訂閱消息系統(tǒng),有如下特性:
通過O(1)的磁盤數(shù)據(jù)結構提供消息的持久化,這種結構對于即使數(shù)以TB的消息存儲也能夠保持長時間的穩(wěn)定性能。(文件追加的方式寫入數(shù)據(jù),過期的數(shù)據(jù)定期刪除) - 高吞吐量:即使是非常普通的硬件Kafka 也可以支持每秒數(shù)百萬的消息。 - 支持通過Kafka 服務器和消費機集群來分區(qū)消息。 - 支持Hadoop 并行數(shù)據(jù)加載。
Kafka相關概念 `Broker :Kafka 集群包含一個或多個服務器,這種服務器被稱為broker[5]
Topic :每條發(fā)布到Kafka 集群的消息都有一個類別,這個類別被稱為Topic 。(物理上不同Topic 的消息分開存儲,邏輯上一個Topic 的消息雖然保存于一個或多個broker 上但用戶只需指定消息的Topic 即可生產或消費數(shù)據(jù)而不必關心數(shù)據(jù)存于何處)
Partition :Parition 是物理上的概念,每個Topic 包含一個或多個Partition 。
Producer :負責發(fā)布消息到Kafka broker
Consumer :消息消費者,向Kafka broker 讀取消息的客戶端。
Consumer Group :每個Consumer 屬于一個特定的Consumer Group (可為每個Consumer 指定group name ,若不指定group name 則屬于默認的group )。
一般應用在大數(shù)據(jù)日志處理或對實時性(少量延遲),可靠性(少量丟數(shù)據(jù))要求稍低的場景使用。 六、參考資料以下是本次分享參考的資料和推薦大家參考的資料。 (1)Jms http://blog.sina.com.cn/s/blog_3fba24680100r777.html http://blog.csdn.net/jiuqiyuliang/article/details/46701559(深入淺出JMS(一)--JMS基本概念) (2)RabbitMQ http://baike.baidu.com/link?url=s2cU-QgOsXan7j0AM5qxxlmruz6WEeBQXX-Bbk0O3F5jt9Qts2uYQARxQxl7CBT2SO2NF2VkzX_XZLqU-CTaPa http://blog.csdn.net/sun305355024sun/article/details/41913105 (3)Zero MQ http://www./2012/08/zeromq-primer.html http://blog.csdn.net/yangbutao/article/details/8498790 http://wenku.baidu.com/link?url=yYoiZ_pYPCuUxEsGQvMMleY08bcptZvwF3IMHo2W1i-ti66YXXPpLLJBGXboddwgGBnOehHiUdslFhtz7RGZYkrtMQQ02DV5sv9JFF4LZnK (4)Kafka http://baike.baidu.com/link?url=qQXyqvPQ1MVrw9WkOGSGEfSX1NHy4unsgc4ezzJwU94SrPuVnrKf2tbm4SllVaN3ArGGxV_N5hw8JTT2-lw4QK http://www./cn/articles/apache-kafka/ http://www./article/3942.shtml 七、本次分享總結以上是本周的分享,主要講解了消息隊列概述,常用消息隊列應用場景(異步處理,應用解耦,流量削鋒,日志處理和消息通訊),JMS Java 消息服務,以及目前流行的幾款消息隊列介紹。 因為時間關系,有些講解的不細致,大家可以問下度娘/Google,希望本次分享對大家有幫助。 分享是快樂的,也是個人成長的過程。文章一般是自己的學習總結,工作經驗,不足之處在所難免,請大家指正,共同進步。
|