Java消息中間件的概述與JMS規範
在介紹消息中間件之前,我們先來看一個故事:
老王的睡前故事:
在很久很久以前,小明隔壁有個姓王的鄰居,姑且就叫隔壁老王吧。隔壁老王有個大女兒,名叫王蘭花秀麗,秀麗從小就愛聽老王講睡前故事,每晚在入睡前都要老王講了睡前故事才能睡的得著。但某一天秀麗到了外地去上大學,老王為了能給秀麗講故事,只能通過打電話的方式進行,如下:
但是有時候可能由於秀麗的手機信號不好或者沒電等情況,導致老王只能不停的聯系,直到電話打通為止。老王內心:我能怎麽辦,我也很絕望啊。雖然秀麗可能會比較晚才能聽到故事,但是這個過程問題也不大。直到某一天,老王的二女兒王蘭花獨秀也到了外地去上學,獨秀也愛聽老王講睡前故事。老王沒辦法,只能也給獨秀打電話。但是這樣就會導致獨秀等電話的時間需要等很久,因為老王得先給秀麗講完再給獨秀講。有時候遇到信號不好的情況就更麻煩了,這樣的話天天都需要耗到很晚,老王也感覺到身體好像被掏空:
經歷了幾個晚上後,老王想著天天這樣子不行啊,搞得身體一天不如一天。於是作為老程序員的老王冥思苦想,想到了一個類似於消息中間件的辦法,那就是註冊一個微信公眾號。老王只需要把每天的睡前故事放到這個公眾號裏,讓兩個女兒來訂閱這個公眾號就行了。那麽兩個女兒不僅能夠不用等待誰先聽完故事,老王也不用天天熬夜了,而且大家都覺得這個公眾號講的故事很好,於是來聽老王講故事的人越來越多,從此老王走上人生巔峰,真是可帶勁了:
借助了微信公總號來講故事後,老王不需要再去關心有多少人要聽故事,老王只需要把故事放到公眾號裏。想聽故事的人只需要有網絡有微信來訂閱這個公眾號即可,這樣不僅讀者能隨時隨地聽故事,而老王也不需要被講故事的事情而耗費太多的時間。這個故事就是詮釋了消息中間件為我們解決的一些問題。
我們再來舉個栗子,例如我們現在有一個登錄系統。我們實現的是通過短信驗證碼進行登錄,所以在用戶登錄時登錄系統需要去調用短信服務發送短信驗證碼給用戶。除了短信服務外,還有一個積分服務,用於加載用戶的積分信息。用戶登錄時還需要記錄日誌,這裏就需要調用一個日誌服務。隨著系統的發展,登錄時需要調用的服務可能越來越多。那麽就意味著,用戶進行一個簡簡單單的登錄操作,就需要等待各種服務調用完成後才能登錄上去,讓登錄的時間變得越來越長,萬一有哪一個服務卡住了那麽用戶的登錄也會卡住,所以登錄系統和相關服務的耦合就很高,導致用戶僅是進行登錄時就得花費很多與登錄功能本身不相關的時間。這就是通過服務調用讓其他系統感知事件發生:
消息中間件就是用於解除這種耦合的,當用戶發送登錄請求並通過驗證後,消息中間件就可以馬上通知用戶登錄成功,而給其他服務投遞消息的工作就由消息中間件去完成,也就是會進行一個異步處理,而用戶是無感知的,不會拖慢用戶的登錄時間。通過消息中間件解耦服務調用:
消息中間件帶來的好處:
- 解耦系統
- 異步通知
- 橫向擴展
- 安全可靠
- 順序保證
- ...
消息中間件概述
什麽是中間件:
- 非底層操作系統軟件,非業務應用軟件,不是直接給最終用戶使用的,不能直接給客戶帶來價值的軟件統稱為中間件。
什麽是消息中間件:
- 關註於數據的發送和接收,利用高效可靠的異步消息傳遞機制集成分布式系統
消息中間件流程圖:
說到消息中間件不得不提一下JMS規範,什麽是JMS規範:
- Java消息服務(Java Message Service)即JMS,是一個Java平臺中關於面向消息中間件的API,用於在兩個應用程序之間,或分布式系統中發送消息,進行異步通信。
同樣的,涉及到消息中間件也需要對AMQP協議有一定的了解,什麽是AMQP協議:
- AMQP(advanced message queuing protocol)是一個提供統一消息服務的應用層標準協議,基於此協議的客戶端與消息中間件可傳遞消息,並不受客戶端/中間件不同產品,不同開發語言條件的限制。
JMS和AMQP對比:
常見消息中間件對比:
名稱 | 描述 | 特性 |
---|---|---|
ActiveMQ | ActiveMQ 是Apache出品的,最流行的,能力強勁的開源消息總線。ActiveMQ 是一個完全支持JMS1.1和J2EE 1.4 規範的JMS Provider實現,盡管JMS規範出臺已經是很久的事情了,但是JMS在當今的J2EE應用中仍然扮演著特殊的地位 | 多種語言和協議編寫客戶端。語言:Java、C/C++、C#、Ruby、Perl、Python、PHP。應用協議:OpenWire、Stomp、REST、WS、Notification、XMPP、AMQP。完全支持JMS1.1和J2EE 1.4規範(持久化、XA消息、事務)。支持虛擬主題、組合目的以及鏡像隊列等 |
RabbitMQ | RabbitMQ是一個開源的AMQP實現,服務端用Erlang語言編寫。用於在分布式系統中存儲轉發消息,在易用性、擴展性、高可用性等方面表現不俗 | 支持多種客戶端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript。是AMQP模型的完整實現(vhost、Exchange、Binding、Routing Key 等)。支持事務及發布確認等特性,可對消息進行持久化 |
Kafka | Kafka是一種高吞吐量的分布式發布訂閱消息系統,是一個分布式的、分區的、可靠的分布式日誌存儲服務。它通過一種獨一無二的設計提供了一個消息系統的功能 | 通過O(1)復雜度的磁盤數據結構提供消息的持久化,這種結構對於即使數以TB的消息存儲也能夠保持長時間的穩定性能。高吞吐量:即使是非常普通的硬件Kafka也可以支持每秒數百萬的消息。 |
綜合評價:
JMS
JMS相關概念:
- 提供者:實現JMS規範的消息中間件服務器
- 客戶端:發送或接收消息的應用程序
- 生產者/發布者:創建發送消息的客戶端
- 消費者/訂閱者:接收並處理消息的客戶端
- 消息:應用程序之間傳遞的數據內容
- 消息模式:在客戶端之間傳遞消息的方式,JMS中定義了主題和隊列兩種模式
JMS消息模式:
隊列模式:
- 客戶端包括生產者和消費者
- 隊列中的消息只能被一個消費者消費
- 消費者可以隨時消費隊列中的消息
隊列模式示意圖:
主題模式:
- 客戶端包括發布者和訂閱者
- 主題中的消息被所有訂閱者消費
- 消費者不能消費訂閱之前就發送到主題中的消息
主題模式示意圖:
JMS編碼接口:
- ConnectionFactory 連接工廠,用於創建連接到消息中間件的連接工廠對象
- Connection 連接,代表了應用程序和服務器之間的通信鏈路
- Destination 目的地,指定消息發布和接收的地點,包括隊列或主題
- Session 會話,表示一個單線程的上下文,用於發送和接收消息
- MessageConsumer 消息消費者,由Session來創建,用於接收發送到目標的消息
- MessageProducer 消息生產者,由Session來創建,用於發送消息到目標
- Message 消息體,是在消費者和生產者之間傳送的對象,一般由消息頭 、 一組消息屬性以及 一個消息體組成
JMS編碼接口之間的關系:
Java消息中間件的概述與JMS規範