RabbitMQ 在上一家公司已經(jīng)接觸過了, 但是懵懵懂懂的. 不是很清楚. 具體怎么個(gè)邏輯.?
這次公司打算搭建新的系統(tǒng). 領(lǐng)導(dǎo)要求研究一下MQ.?
經(jīng)過研究得出的結(jié)論是. MSMQ的設(shè)計(jì)理念不適合做系統(tǒng)的底層框架. 他不適合做分布式系統(tǒng). 最主要的是. MSMQ如果沒有消費(fèi)者, 默認(rèn)消息是一直存在的.?
而RabbitMQ的設(shè)計(jì)理念是.只要有接收消息的隊(duì)列. 郵件就會存放到隊(duì)列里. 直到訂閱人取走. . 如果沒有可以接收這個(gè)消息的消息隊(duì)列. 默認(rèn)是拋棄這個(gè)消息的..
下面就把我的研究結(jié)果寫一下.
如何在新的系統(tǒng)中使用RabbitMQ.
系統(tǒng)設(shè)計(jì)的兩個(gè)重大問題.?
第一條要滿足未來的業(yè)務(wù)需求的不斷變化和增加. 也就是可擴(kuò)展性.?
第二條要滿足性能的可伸縮性. 也就是可集群性…通過增加機(jī)器能處理更多的請求?
第三條要解耦合.?
如果不解耦合, 未來業(yè)務(wù)增加或變更的時(shí)候你還在修改3年前寫的代碼.試問你有多大的把握保證升級好系統(tǒng)不出問題? 如何可以寫新的代碼而不用修改老代碼所帶來的好處誰都知道…?
第四條簡單易懂.
以上4條在任何一個(gè)系統(tǒng)中都要遵循的原則. 以前是無法做到的. 自從有了MQ以后. 這些都可以同時(shí)做到了.?
以前的設(shè)計(jì)理念是把系統(tǒng)看作一個(gè)人,按照工作的指令從上到下的執(zhí)行.?
現(xiàn)在要建立的概念是, 把系統(tǒng)的各個(gè)功能看作不同的人. 人與人之間的溝通通過消息進(jìn)行交流傳遞信息…?
有了MQ以后把一個(gè)人的事情分給了不同的人, 分工合作所帶來的好處是專業(yè)化, 并行化. 當(dāng)然也引入了一些麻煩,性能開銷多一些, 工作任務(wù)的完整性不能立即得到反饋.幸好我們可以通過最終一致性.來解決這個(gè)麻煩的問題…
下面進(jìn)入正題.
第一個(gè)問題RabbitMQ是如何支持可擴(kuò)展性的.
如上圖, 寄件人P是系統(tǒng)的一個(gè)功能模塊. 用來發(fā)送消息. 一般是在某些重要的業(yè)務(wù)狀態(tài)變更時(shí)發(fā)送消息. 例如: 新訂單產(chǎn)生時(shí), 訂單已打包時(shí), 訂單已出庫時(shí), 訂單已發(fā)出時(shí).
那么當(dāng)事件 新訂單產(chǎn)生時(shí), 我們需要把這個(gè)信息告訴誰呢? 給財(cái)務(wù)? 還是給倉庫發(fā)貨??
這個(gè)地方最大的重點(diǎn)是. 當(dāng)事件產(chǎn)生時(shí). 根本不關(guān)心. 該投遞給誰.?
我只要把我的重要的信息投到這個(gè)亂七八糟的MQ系統(tǒng)即可. 其它人你該干嘛干嘛. 反正我的任務(wù)完成了. (有沒有甩手掌柜的感覺..)
我只要告訴系統(tǒng),我的事件屬于那一類.?
例如: “某某省.某某市.某某公司.產(chǎn)生新訂單”?
那么這個(gè)地址就屬于 投遞地址.. 至于這個(gè)地址具體投到哪個(gè)郵箱那是郵局的事情.?
當(dāng)然還有一些具體的訂單內(nèi)容也屬于要告訴系統(tǒng)的內(nèi)容.
那么下一個(gè)問題來了, 郵局怎么知道 你的這個(gè)消息應(yīng)該投遞給誰??
參考我們現(xiàn)實(shí)世界中的郵寄系統(tǒng).是默認(rèn)的省市縣這么投遞的. 這是固定思維.?
但是我們的MQ系統(tǒng)中不是這樣的. 是先有收件人的郵箱. (隊(duì)列Queue). MQ才能投遞. 否則就丟棄這個(gè)信息…
所以MQ系統(tǒng)應(yīng)該先有收件人的郵箱 Queue 也就是隊(duì)列. 才能接收到信息.?
再有郵局?
再有發(fā)信息的人.
RabbitMQ能實(shí)現(xiàn)系統(tǒng)擴(kuò)展的一個(gè)重要功能在于, 可以兩個(gè)郵箱收同一個(gè)地址的信.
翻譯成專業(yè)的話 RabbitMQ 可以 兩個(gè)隊(duì)列Queue訂閱同一個(gè)RoutingKey的信息..?
RabbitMQ在投遞的時(shí)候,會把一份信息,投遞到多個(gè)隊(duì)列郵箱中Queue…?
這是系統(tǒng)可擴(kuò)展性的基礎(chǔ).
第二個(gè)問題RabbitMQ如何滿足性能的可伸縮性. 也就是可集群性
先上圖?
從上圖, 可以看到. 性能擴(kuò)展的關(guān)鍵點(diǎn)就在于 訂閱人C1, 訂閱人C2 輪流收到郵箱隊(duì)列里面的信息, 訂閱人C1和訂閱人C2收到的信息內(nèi)容不同, 但都屬于同一類….?
所以. 訂閱人C1和訂閱人C2是干同一種工作的客戶端.用來提高處理能力.
上面說完了,如何使用. 下面再分析一下幾個(gè)關(guān)注點(diǎn).
如果訂閱人的down機(jī)了. 信息會丟失嗎?
? ? 事實(shí)上是不會的. 只要有郵箱(隊(duì)列Queue)存在.信息就一直存在, 除非訂閱人去取走.
如果訂閱人一直down機(jī), 郵箱隊(duì)列能存多少信息?會不會爆掉?
? 理論上和實(shí)際上都是有上限的不可能無限多. 具體多少看硬盤吧..我沒測到過上限.
我這篇文章并不打算講解郵局的4種投遞模式. 有其它文章講的很好. 我只打算使用topic這種模式. 因?yàn)樗`活一些.
再說一下我的另外兩個(gè)觀點(diǎn).?
不要在業(yè)務(wù)程序中用代碼定義創(chuàng)建 郵局 ExChange. 和郵箱Queue隊(duì)列 這屬于系統(tǒng)設(shè)計(jì)者要構(gòu)架的事情. 要有專門獨(dú)立的程序和規(guī)則去創(chuàng)建. 這樣可以統(tǒng)一管理事件類型.避免過多的亂七八糟的RoutingKey混亂.
我的理解認(rèn)為?
消息系統(tǒng)的分布式可擴(kuò)展的實(shí)現(xiàn)在于消息廣播, 集群性的實(shí)現(xiàn)在于郵箱隊(duì)列.?
RabbitMQ是先廣播后隊(duì)列的.
Exchange: 就是郵局的概念等同于 中國郵政和順豐快遞剩岳、?
routingkey: 就是郵件地址的概念.?
queue: 就是郵箱接收軟件养盗,但是可以接收多個(gè)地址的郵件钻蹬,通過bind實(shí)現(xiàn)。?
producer: 消息生產(chǎn)者,就是投遞消息的程序誓军。?
consumer:消息消費(fèi)者巾腕,就是接受消息的程序。?
channel:消息通道闪湾,在客戶端的每個(gè)連接里冲甘,可建立多個(gè)channel,每個(gè)channel代表一個(gè)會話任務(wù)途样。
給大家推薦一個(gè)程序員學(xué)習(xí)交流群:960439918江醇。點(diǎn)擊鏈接加入群聊【java高級架構(gòu)交流群】:https://jq.qq.com/?_wv=1027&k=5fozFzF群里有分享的視頻,還有思維導(dǎo)圖群公告有視頻何暇,都是干貨的陶夜,你可以下載來看。主要分享分布式架構(gòu)裆站、高可擴(kuò)展条辟、高性能、高并發(fā)宏胯、性能優(yōu)化羽嫡、Spring boot、Redis胳嘲、ActiveMQ厂僧、Nginx、Mycat了牛、Netty颜屠、Jvm大型分布式項(xiàng)目實(shí)戰(zhàn)學(xué)習(xí)架構(gòu)師視頻。