標籤:訊息中介軟體 JMS ActiveMQ RabbitMQ 分布式
為什麼需要使用訊息中介軟體
在介紹訊息中介軟體之前,我們先來看一個故事:
老王的睡前故事:
在很久很久以前,小明隔壁有個姓王的鄰居,姑且就叫隔壁老王吧。隔壁老王有個大女兒,名叫王蘭花秀麗,秀麗從小就愛聽老王講睡前故事,每晚在入睡前都要老王講了睡前故事才能睡的得著。但某一天秀麗到了外地去上大學,老王為了能給秀麗講故事,只能通過打電話的方式進行,如下:
但是有時候可能由於秀麗的手機訊號不好或者沒電等情況,導致老王只能不停的聯絡,直到電話打通為止。老王內心:我能怎麼辦,我也很絕望啊。雖然秀麗可能會比較晚才能聽到故事,但是這個過程問題也不大。直到某一天,老王的二女兒王蘭花獨秀也到了外地去上學,獨秀也愛聽老王講睡前故事。老王沒辦法,只能也給獨秀打電話。但是這樣就會導致獨秀等電話的時間需要等很久,因為老王得先給秀麗講完再給獨秀講。有時候遇到訊號不好的情況就更麻煩了,這樣的話天天都需要耗到很晚,老王也感覺到身體好像被掏空:
經曆了幾個晚上後,老王想著天天這樣子不行啊,搞得身體一天不如一天。於是作為老程式員的老王冥思苦想,想到了一個類似於訊息中介軟體的辦法,那就是註冊一個公眾號。老王只需要把每天的睡前故事放到這個公眾號裡,讓兩個女兒來訂閱這個公眾號就行了。那麼兩個女兒不僅能夠不用等待誰先聽完故事,老王也不用天天熬夜了,而且大家都覺得這個公眾號講的故事很好,於是來聽老王講故事的人越來越多,從此老王走上人生巔峰,真是可帶勁了:
藉助了公總號來講故事後,老王不需要再去關心有多少人要聽故事,老王只需要把故事放到公眾號裡。想聽故事的人只需要有網路有來訂閱這個公眾號即可,這樣不僅讀者能隨時隨地聽故事,而老王也不需要被講故事的事情而耗費太多的時間。這個故事就是詮釋了訊息中介軟體為我們解決的一些問題。
我們再來舉個栗子,例如我們現在有一個登入系統。我們實現的是通過簡訊驗證碼進行登入,所以在使用者登入時登入系統需要去調用簡訊服務傳送簡訊驗證碼給使用者。除了簡訊服務外,還有一個積分服務,用於載入使用者的積分資訊。使用者登入時還需要記錄日誌,這裡就需要調用一個Log Service。隨著系統的發展,登入時需要調用的服務可能越來越多。那麼就意味著,使用者進行一個簡簡單單的登入操作,就需要等待各種服務調用完成後才能登入上去,讓登入的時間變得越來越長,萬一有哪一個服務卡住了那麼使用者的登入也會卡住,所以登入系統和相關服務的耦合就很高,導致使用者僅是進行登入時就得花費很多與登入功能本身不相關的時間。這就是通過服務調用讓其他系統感知事件發生:
訊息中介軟體就是用於解除這種耦合的,當使用者發送登入請求並通過驗證後,訊息中介軟體就可以馬上通知使用者登入成功,而給其他服務投遞訊息的工作就由訊息中介軟體去完成,也就是會進行一個非同步處理,而使用者是無感知的,不會拖慢使用者的登入時間。通過訊息中介軟體解耦服務調用:
訊息中介軟體帶來的好處:
- 解耦系統
- 非同步通知
- 橫向擴充
- 安全可靠
- 順序保證
- ...
訊息中介軟體概述
什麼是中介軟體:
- 非底層作業系統軟體,非業務應用軟體,不是直接給終端使用者使用的,不能直接給客戶帶來價值的軟體統稱為中介軟體。
什麼是訊息中介軟體:
- 關注於資料的發送和接收,利用高效可靠的非同步訊息傳遞機制整合分布式系統
訊息中介軟體流程圖:
說到訊息中介軟體不得不提一下JMS規範,什麼是JMS規範:
- JavaMessage Service(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規範