目錄
一,RabbitMQ是什么?
二,RabbitMQ架構
2.1 首先我們來看下RabbitMQ里面的心概念Queue是什么?
2.2 交換器Exchange
2.3?RabbitMQ是什么?
2.4 重點看下優先級隊列是什么?
三,RabbitMQ集群
3.1 普通集群模式
3.2?鏡像隊列集群
一,RabbitMQ是什么?
假設我們程序員維護了2個服務,A服務負責轉發用戶請求到B服務,B服務是個算法服務,GPU資源有限,當請求量達到B服務處理不過來的時候,希望能有限處理我們的VIP服務(充錢的作用來了,哈哈......),那么問題來了,當普通用戶和會員用戶同時發起請求,怎樣才能做到會員優先?
這個問題好辦,沒有什么是加一層中間層解決不了的,加一層不夠,那就再加一層,哈哈
這次我們要加的中間層就是消息隊列RabbitMQ
二,RabbitMQ架構
2.1 首先我們來看下RabbitMQ里面的心概念Queue是什么?
消息隊列本質上就是類似鏈表的獨立進程,鏈表里的每一個節點是一個消息,它介于生產者和消費者之間,在流量高峰時先慢慢暫存數據,然后再慢慢消費數據,可以很好的保護消費者,也就是削峰填谷,這個類似鏈表的進程就是隊列
但消息也分很多種類,比如訂單消息,用戶消息,商品消息,為了更好的管理不同種類的數據,可以提供多個隊列,生產者可以自定義隊列的名字,并且根據需要將消息投遞到不同的隊列中,每個queue都是獨立的進程,某個進程掛了,不會影響其他進程工作
2.2 交換器Exchange
有些生產者想將消息發到一個Queue中,有些則是發給多個Queue中,甚至廣播給所有Queue,于是我們還需要一個可以定制消息路由分發的策略的組件,交換器Exchange,將它與Queue綁定在一起,通過一個類似正則表達式的字符串,聲明綁定的關系,讓用戶根據需要,選擇要投遞的序列,
這些維護在Exchange里面的路由方式和綁定關系我們稱為元數據
2.3?RabbitMQ是什么?
像這種包含多個Queue進程和Exchange組件的消息隊列,就是所謂的?RabbitMQ
每一臺服務上的RabbitMQ的實例,就代表一個broker,大佬們在這個架構的基礎上為RabbitMQ實現了各種豐富的特性,比如延時隊列,死信隊列,優先級隊列
2.4 重點看下優先級隊列是什么?
RabbitMQ支持在生產者發送消息時,為消息標上優先級,消費者總是消費優先級高的消息,所以我們前文中提到的VIP問題,就可以通過優先級隊列來實現
我們可以在A服務中,根據用戶的等級,為消息打上對應的優先級,在投遞到RabbitMQ中,B服務永遠消費高優消息,當高優消息處理完后,再處理普通消息(這就是氪金的用處)
三,RabbitMQ集群
雖然RabbitMQ功能很豐富,但是它的架構就是個單實例節點,有些過于簡單了,像什么高可用,高可擴展是一個都不沾,我們來看下RabbitMQ是怎么擴展這部分能力的?那就是RabbitMQ集群
既然單節點存在諸多問題,那就讓多個節點構成集群,我們可以在多個服務器上各部署一個RabbitMQ實例,并通過RabbitMQ提供的命令將這些實例組成一個集群,RabbitMQ支持多種集群模式,普通集群,鏡像隊列集群,Quorum隊列集群
3.1 普通集群模式
在普通集群模式中,每個broker都是一個完整功能的RabbitMQ實例,都能進行讀寫,他們之間會互相同步Exchange里面的元數據,但不會同步Queue的數據
假設Queue1,Queue2,Queue3分別部署在broker1,broker2,broker3中
對于寫操作來說:
生產者將消息寫入到broker1的Queue1中,Queue里的數據并不會同步給其他的broker,但如果此時Exchang中的元數據有變化,則會將Exchange的元數據同步到其他的broker上
對于讀操作來說:
消費者想要讀取Queue1中的數據時,如果訪問的是broker1,則直接返回Queue1的數據,如果訪問的是broker2,broker2則會根據Exchange里的元數據,從broker1里面讀取數據,再返回給消費者,這樣就可以通過增加broker,提升RabbitMQ集群整體的吞吐量,保證了擴展性
但問題也很明顯,雖然支持讀寫Queue的數量是增加了,但對于單個Queue本身的讀寫能力并沒有提升,而且更重要的是每個Broker依然有單點問題,Broker之間并沒有同步Queue里面的數據,某個Queue所在的Broker要是掛了,就沒辦法讀寫這個Queue了,這和高可用毫不沾邊,有更好的方案么?答案是有,請看3,2?
3.2?鏡像隊列集群
我們可以在普通集群的基礎上上,給Queue增加幾個副本到其它的broker上,他們有主從關系,主Queue負責讀寫數據,從Queue負責同步復制主Queue數據,所以從Queue也叫鏡像隊列,一旦主Queue所在的Broker掛了,從Queue就可以頂上成為新的主Queue,實現高可用,這就是所謂的鏡像隊列集群
對于寫操作:
數據寫入主Queue后,會將Exchange和Queue數據同步給其他的Broker
對于讀操作:
消費者讀取數據時,如果訪問的是主Queue所在的broker,則直接返回數據,否則當前broker會從主Queue所在的broker上讀區數據,之后返回給消費者
但是這個方案的缺點也很明顯,broker之間同步的數據量會變大,集群節點越多,帶寬壓力越大,本質上鏡像隊列集群是犧牲吞吐量換取的高可用,反觀前面的普通集群,雖然吞吐高,但是卻犧牲了高可用