目錄
RabbitMQ學習總結 第一篇:理論篇
RabbitMQ學習總結 第二篇:快速入門HelloWorld
RabbitMQ學習總結 第三篇:工作隊列Work Queue
RabbitMQ學習總結 第四篇:發布/訂閱 Publish/Subscribe
RabbitMQ學習總結 第六篇:Topic類型的exchange
RabbitMQ學習總結 第七篇:RCP(遠程過程調用協議)
博客很久沒有更新了,這段時間主要是學習設計模式,一直想寫一系列的設計模式相關博文,但是設計模式理解起來說難也不難,說簡單也不簡單,但要想能深入理解並在項目架構中運用自如的話,還是得花點時間好好積累的。扯得有點遠了~
今天咱們來聊一聊消息隊列(MQ),以RabbitMQ為例。
1. 定義
消息隊列:在消息的傳輸過程中保存消息的的容器。
這是一個較為經典的消費-生產者模型,說起來比較抽象,打個比方:A線程需要給B線程發送消息(A、B線程不一定是在同一台機器上的),A線程先把消息發送到消息隊列服務器上,然后B線程去讀取或是訂閱消息服務器上消息隊列中的消息,線程A和B之間並沒有進行直接通信。MQ服務器在中間起到中繼的作用。
2. 適用的應用場景
比較適合異步傳輸,這里解釋一下什么是異步和同步。
異步:發送方不關心消息有沒有發送成功,只發送消息,不去獲取消息是否發送成功。
同步:發送方關心消息是否發送成功,發送消息后,會等待接收方返回狀態碼,根據狀態碼來判斷是否發送成功,然后執行相對於的動作。
下邊以Http中的同步和異步為例:
如:普通的B/S架構客戶端和服務器端之間的通信就是同步的,即提交請求 ---> 等待服務器處理完畢返回消息 ---> 拿到服務器返回的消息,處理完畢。
如:Ajax技術就是異步的,請求通過事件觸發 ---> 服務器處理(瀏覽器不用等待,仍可以做其他的事情) ---> 處理完畢。
有人可能會好奇說應用場景怎么說到了同步和異步,那說明你還不是很理解技術和應用場景之間的緊密聯系。
3. RabbitMQ
在消息隊列中有很多類似的產品,以后我會獨立發一篇博文來經行說明。我們這里以RabbitMQ為例。
RabbitMQ是AMQP(高級消息隊列協議)的一個標准實現,關於它的快速入門,可以在這里查看:http://www.rabbitmq.com/getstarted.html。
3.1. 角色概念
每個開源項目都有自己的設計方法以及模塊角色,RabbitMQ也不例外。結構圖如下:

Broker:即消息隊列服務器實體
Exchange:消息交換機,它指定消息按什么規則,路由到哪個隊列。
Queue:消息隊列載體,每個消息都會被投入到一個或多個隊列。
Binding:綁定,它的作用就是把exchange和queue按照路由規則綁定起來。
Routing Key:路由關鍵字,exchange根據這個關鍵字進行消息投遞。
vhost:虛擬主機,一個broker里可以開設多個vhost,用作不同用戶的權限分離。
producer:消息生產者,就是投遞消息的程序。
consumer:消息消費者,就是接受消息的程序。
channel:消息通道,在客戶端的每個連接里,可建立多個channel,每個channel代表一個會話任務。
3.2. 工作過程
- 生產者客戶端:
- 客戶端連接到RabbitMQ服務器上,打開一個消息通道(channel);
- 客戶端聲明一個消息交換機(exchange),並設置相關屬性。
- 客戶端聲明一個消息隊列(queue),並設置相關屬性。
- 客戶端使用routing key在消息交換機(exchange)和消息隊列(queue)中建立好綁定關系。
- 客戶端投遞消息都消息交換機(exchange)上
- 客戶端關閉消息通道(channel)以及和服務器的連接。
- 服務器端:
exchange接收到消息后,根據消息的key(這個key的產生規則暫時沒研究,有知道的小伙伴可以留言告訴我)和以及設置的binding,進行消息路由,將消息投遞到一個或多個消息隊列中。
關於exchange也有幾個類型:
(1). Direct交換機:完全根據key進行投遞。例如,綁定時設置了routing key為abc,客戶端提交信息提交信息時只有設置了key為abc的才會投遞到隊列;
(2).Topic交換機:在key進行模式匹配后進行投遞。例如:符號”#”匹配一個或多個字符,符號”*”匹配一串連續的字母字符,例如”abc.#”可以匹配”abc.def.ghi”,而”abc.*”只可以匹配”abc.def”。
(3).Fanout交換機:它采取廣播模式,消息進來時,將會被投遞到與改交換機綁定的所有隊列中。
- 消費者客戶端:
(暫時未研究,后續更新)
3.3. RabbitMQ的消息持久化
RabbitMQ支持數據持久化,也就是把數據寫在磁盤上,可以增加數據的安全性。消息隊列持久化包括三個部分:
- 消息交換機(exchange)持久化,在聲明時指定durable為1
- 消息隊列(queue)持久化,在聲明時指定durable為1
- 消息持久化,在投遞時指定delivery_mode為2(1是非持久化)
如果消息交換機(exchange)和消息隊列(queue)都是持久化的話,那么他們之間的綁定(Binding)也是持久化的。如果消息交換機和消息隊列之間一個持久化、一個非持久化,那么就不允許綁定。
