為什么要使用消息中間件
案例:假如我們開發了一個商品搶購網站。這個網站的目的就是在某一時間點進行搶購商品,同時要求用戶注冊,在注冊的時候會同時給用戶電話和郵箱中發送驗證碼,以便完成信息注冊。傳統做法應該是這樣的。兩種方式,並行即啟用兩個線程,當用戶提交信息后,分別去發送郵件和發送短信。這種方式很明顯比串行的方式更快。當我們加入消息隊列后,處理方式如下圖:

加入消息中間件后,我們只需要注冊信息存庫后,給消息隊列中添加一條消息就完事了。然后郵件服務和短信服務分別去消費消息即可。

當用戶注冊完成后,到了搶購商品的時間,大家都去搶購某個商品的時候這個量很大。消息隊列可以設置隊列長度來保證系統的穩定性。當隊列滿了的時候,則不再處理這些用戶請求。
因此我們可以總結一下消息隊列的特點:
- 異步處理 -- 用戶注冊信息提交后,直接返回響應。然后郵件服務和短信服務監聽到隊列有消息后去主動處理
- 應用解耦 -- 用戶注冊流程分成了三個服務,注冊服務、郵件服務、短信服務互不干擾。
- 流量削峰 -- 控制用戶請求,以防系統奔潰。
常見消息中間件介紹
ActiveMQ:apache出品,能力強勁的開源消息總線,完全支持jms規范的消息中間件。api豐富,在傳統行業的中小型企業中應用廣泛。缺點:服務性能和數據存儲性能不好。
Kafka:apache頂級項目,追求高吞吐量。一開始的目的是用於日志收集和傳輸。不支持事務,對消息重復,丟失,錯誤沒有嚴格的請求。適合產生大量數據的互聯網服務的數據收集業務。
RocketMQ:阿里開源中間件,目前已孵化成apache頂級項目,純java開發,思路起源於kafka,對消息的可靠性傳輸和事務性做了優化。特點:高吞吐量、高可用。適合大規模分布式系統應用。目前在阿里集團被廣泛使用,用於交易、充值,流計算,日志處理,消息推送等。現在推出了商業版,有些功能對外不開發。
RabbitMQ:是一個開源的消息代理和隊列服務器,用來通過普通協議在完全不同的應用之間共享數據,RabbitMQ是使用ErLang語言來編寫的,並且基於AMQP協議。erlang語言開發,性能較好,高並發。社區活躍度高,網上資料比較多。
什么是AMQP協議
AMQP(Advanced Message Queuing Protocol,高級消息隊列協議)是一個進程間傳遞異步消息的網絡協議。
涉及到的具體概念:
- server - 又稱broker,接收客戶端的鏈接,實現amqp實體服務。
- Connection - 鏈接,應用程序跟broker的網絡鏈接。
- channel - 網絡信道,幾乎所有的操作都是在channel中進行,數據的流轉都要在channel上進行。channel是進行消息讀寫的通道。客戶端可以建立多個channel,每個channel代表一個會話任務。
- message - 消息,服務器與應用程序之間傳送的數據。由properties和body組成。properties可以對消息進行修飾,比如消息的升級,延遲等高級特性。body就是消息體的內容。
- virtual host - 虛擬主機,用於進行邏輯隔離,最上層的消息路由,一個虛擬地址里面可以有多個交換機。exchange和消息隊列message quene。
- exchange - 交換機,接收消息,根據路由器轉發消息到綁定的隊列。
- binding - 綁定,交換機和隊列之間的虛擬鏈接,綁定中可以包含routing key。
- routing key - 一個路由規則,虛擬機可以用它來確定如何路由一個特定消息。
- quene - 消息隊列,保存消息並將它們轉發給消費者。
詳細了解AMQP協議可參考這篇文章--------詳解AMQP協議
交換機簡單介紹
exchange:接收消息,並根據路由鍵轉發消息所綁定的隊列。
交換機的屬性:
name:交換機的名稱
type:交換機的類型direct,topic,fanout,headers
durability:是否需要持久化,true為持久化。
auto delete:當最后一個綁定到exchange上的隊列刪除后,自動刪除該exchange。
internal:當前exchange是否用於rabbitMQ內部使用,默認為false。
arguments:可擴展參數。用戶自自定義的交換機時,用到的參數。
交換機常用的類型為direct,topic,fanout。headers不常用。
direct(直連交換機):
-
所有發送到directExchange的消息被轉發到RouteKey中指定的Queue
-
rabbitmq有一個自帶的exchange叫default exchange,這個交換機是direct類型的。rabbitmq會讓路由鍵跟隊列名相等進行綁定。
topic(主題交換機):
-
所有發送到topic exchange的消息被轉發到所有關心RouteKey的Queue上
-
Exchange將RouteKey和某些隊列進行模糊匹配,此時隊列需要綁定一個Topic
模糊匹配可以使用通配符:
#可以匹配一個或多個詞
*只能匹配一個詞
比如:"log.#"可以匹配到“log.info.oa”。“log.*”只會匹配到“log.error”
Fanout(扇型交換機):
-
不處理路由鍵,只需要簡單的將隊列綁定到交換機上。
-
發送到交換機的消息都會被轉發到與該交換機綁定的所有隊列上
-
fanout交換機轉發消息是最快的。
如果文章對您有幫助,請記得點贊關注喲~
歡迎大家關注我的公眾號:字節傳說,每日推送技術文章供大家學習參考。
