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

轉自: https://blog.csdn.net/phker/article/details/71211895

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代表一個會話任務。

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

參考文章:
http://blog.csdn.net/samxx8/article/details/47417133
http://www.cnblogs.com/zlfoak/p/5521673.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章