1. 程式人生 > >RabbitMQ的深入理解和最簡單的用途說明

RabbitMQ的深入理解和最簡單的用途說明

RabbitMQ 在上一家公司已經接觸過了, 但是懵懵懂懂的. 不是很清楚. 具體怎麼個邏輯.
這次公司打算搭建新的系統. 領導要求研究一下MQ.
經過研究得出的結論是. MSMQ的設計理念不適合做系統的底層框架. 他不適合做分散式系統. 最主要的是. MSMQ如果沒有消費者, 預設訊息是一直存在的.
而RabbitMQ的設計理念是.只要有接收訊息的佇列. 郵件就會存放到佇列裡. 直到訂閱人取走. . 如果沒有可以接收這個訊息的訊息佇列. 預設是拋棄這個訊息的..

下面就把我的研究結果寫一下.

如何在新的系統中使用RabbitMQ.

系統設計的兩個重大問題.
第一條要滿足未來的業務需求的不斷變化和增加. 也就是可擴充套件性.
第二條要滿足效能的可伸縮性. 也就是可叢集性…通過增加機器能處理更多的請求
第三條要解耦合.
如果不解耦合, 未來業務增加或變更的時候你還在修改3年前寫的程式碼.試問你有多大的把握保證升級好系統不出問題? 如何可以寫新的程式碼而不用修改老程式碼所帶來的好處誰都知道…
第四條簡單易懂.

以上4條在任何一個系統中都要遵循的原則. 以前是無法做到的. 自從有了MQ以後. 這些都可以同時做到了.
以前的設計理念是把系統看作一個人,按照工作的指令從上到下的執行.
現在要建立的概念是, 把系統的各個功能看作不同的人. 人與人之間的溝通通過訊息進行交流傳遞資訊…
有了MQ以後把一個人的事情分給了不同的人, 分工合作所帶來的好處是專業化, 並行化. 當然也引入了一些麻煩,效能開銷多一些, 工作任務的完整性不能立即得到反饋.幸好我們可以通過最終一致性.來解決這個麻煩的問題…

下面進入正題.

第一個問題RabbitMQ是如何支援可擴充套件性的.

這裡寫圖片描述

如上圖, 寄件人P是系統的一個功能模組. 用來發送訊息. 一般是在某些重要的業務狀態變更時傳送訊息. 例如: 新訂單產生時, 訂單已打包時, 訂單已出庫時, 訂單已發出時.

那麼當事件 新訂單產生時, 我們需要把這個資訊告訴誰呢? 給財務? 還是給倉庫發貨?
這個地方最大的重點是. 當事件產生時. 根本不關心. 該投遞給誰.
我只要把我的重要的資訊投到這個亂七八糟的MQ系統即可. 其它人你該幹嘛幹嘛. 反正我的任務完成了. (有沒有甩手掌櫃的感覺..)

我只要告訴系統,我的事件屬於那一類.
例如: “某某省.某某市.某某公司.產生新訂單”
那麼這個地址就屬於 投遞地址.. 至於這個地址具體投到哪個郵箱那是郵局的事情.
當然還有一些具體的訂單內容也屬於要告訴系統的內容.

那麼下一個問題來了, 郵局怎麼知道 你的這個訊息應該投遞給誰?
參考我們現實世界中的郵寄系統.是預設的省市縣這麼投遞的. 這是固定思維.
但是我們的MQ系統中不是這樣的. 是先有收件人的郵箱. (佇列Queue). MQ才能投遞. 否則就丟棄這個資訊…

所以MQ系統應該先有收件人的郵箱 Queue 也就是佇列. 才能接收到資訊.
再有郵局
再有發信息的人.

RabbitMQ能實現系統擴充套件的一個重要功能在於, 可以兩個郵箱收同一個地址的信.
翻譯成專業的話 RabbitMQ 可以 兩個佇列Queue訂閱同一個RoutingKey的資訊..
RabbitMQ在投遞的時候,會把一份資訊,投遞到多個佇列郵箱中Queue…
這是系統可擴充套件性的基礎.

第二個問題RabbitMQ如何滿足效能的可伸縮性. 也就是可叢集性

先上圖
這裡寫圖片描述

從上圖, 可以看到. 效能擴充套件的關鍵點就在於 訂閱人C1, 訂閱人C2 輪流收到郵箱佇列裡面的資訊, 訂閱人C1和訂閱人C2收到的資訊內容不同, 但都屬於同一類….
所以. 訂閱人C1和訂閱人C2是幹同一種工作的客戶端.用來提高處理能力.

上面說完了,如何使用. 下面再分析一下幾個關注點.

如果訂閱人的down機了. 資訊會丟失嗎?

    事實上是不會的. 只要有郵箱(佇列Queue)存在.資訊就一直存在, 除非訂閱人去取走.

如果訂閱人一直down機, 郵箱佇列能存多少資訊?會不會爆掉?

   理論上和實際上都是有上限的不可能無限多. 具體多少看硬碟吧..我沒測到過上限.

我這篇文章並不打算講解郵局的4種投遞模式. 有其它文章講的很好. 我只打算使用topic這種模式. 因為它更靈活一些.

再說一下我的另外兩個觀點.
不要在業務程式中用程式碼定義建立 郵局 ExChange. 和郵箱Queue佇列 這屬於系統設計者要構架的事情. 要有專門獨立的程式和規則去建立. 這樣可以統一管理事件型別.避免過多的亂七八糟的RoutingKey混亂.

我的理解認為
訊息系統的分散式可擴充套件的實現在於訊息廣播, 叢集性的實現在於郵箱佇列.
RabbitMQ是先廣播後佇列的.

Exchange: 就是郵局的概念等同於 中國郵政和順豐快遞、
routingkey: 就是郵件地址的概念.
queue: 就是郵箱接收軟體,但是可以接收多個地址的郵件,通過bind實現。
producer: 訊息生產者,就是投遞訊息的程式。
consumer:訊息消費者,就是接受訊息的程式。
channel:訊息通道,在客戶端的每個連線裡,可建立多個channel,每個channel代表一個會話任務。

其它關於投遞模式, 請參考下面的兩篇文章.