在專案中想要 rabbitmq 變得更加健壯,就要使得其變成高可用,所以我們要搭建乙個 rabbitmq 集群,這樣你可以從任何一台 rabbitmq 故障中得以倖免,並且應用程式能夠持續執行而不會發生阻塞。而 rabbitmq 本身是基於 erlang 編寫的,erlang 天生支援分布式(通過同步 erlang 集群各節點的 cookie 來實現),因此不需要像 activemq、kafka 那樣通過 zookeeper 分別來實現 ha 方案和儲存集群的元資料。
元資料
rabbitmq 內部有各種基礎構件,包括佇列、交換器、繫結、虛擬主機等,他們組成了 amqp 協議訊息通訊的基礎,而這些構件以元資料的形式存在,它始終記錄在 rabbitmq 內部,它們分別是:
在單一節點上,rabbitmq 會將上述元資料儲存到記憶體上,如果是磁碟節點(下面會講),還會儲存到磁碟上。
集群中的佇列
這裡有個問題需要思考,rabbitmq 缺省會將訊息冗餘到所有節點上嗎?這樣聽起來正符合高可用的特性,只要集群上還有乙個節點存活,那麼就可以繼續進行訊息通訊,但這也隨之為 rabbitmq 帶來了致命的缺點:
每次發布訊息,都要把它擴散到所有節點上,而且對於磁碟節點來說,每一條訊息都會觸發磁碟活動,這會導致整個集群內效能負載急劇拉公升。
如果每個節點都有所有佇列的完整內容,那麼新增節點不會給你帶來額外的儲存空間,也會帶來木桶效應,舉個例子,如果集群內有個節點儲存了 3g
佇列內容,那麼在另外乙個只有 1g 儲存空間的節點上,就會造成記憶體空間不足的情況,也就是無法通過集群節點的擴容提高訊息積壓能力。
解決這個問題就是通過集群中唯一節點來負責任何特定佇列,只有該節點才會受佇列大小的影響,其它節點如果接收到該佇列訊息,那麼就要根據元資料資訊,傳遞給佇列所有者節點(也就是說其它節點上只儲存了特定佇列所有者節點的指標)。這樣一來,就可以通過在集群內增加節點,儲存更多的佇列資料。
分布交換器
交換器其實是我們想象出來的,它本質是一張查詢表,裡面包括了交換器名稱和乙個佇列的繫結列表,當你將訊息發布到交換器中,實際上是你所在的通道將訊息上的路由鍵與交換器的繫結列表進行匹配,然後將訊息路由出去。有了這個機制,那麼在所有節點上傳遞交換器訊息將簡單很多,而 rabbitmq 所做的事情就是把交換器拷貝到所有節點上,因此每個節點上的每條通道都可以訪問完整的交換器了。
記憶體節點與磁碟節點
關於上面佇列所說的問題與解決辦法,又有了乙個伴隨而來的問題出現:如果特定佇列的所有者節點發生了故障,那麼該節點上的佇列和關聯的繫結都會消失嗎?
如果是記憶體節點,那麼附加在該節點上的佇列和其關聯的繫結都會丟失,並且消費者可以重新連線集群並重新建立佇列;
如果是磁碟節點,重新恢復故障後,該佇列又可以進行傳輸資料了,並且在恢復故障磁碟節點之前,不能在其它節點上讓消費者重新連到集群並重新建立佇列,如果消費者繼續在其它節點上宣告該佇列,會得到乙個
404 not_found
錯誤,這樣確保了當故障節點恢復後加入集群,該節點上的佇列訊息不回丟失,也避免了佇列會在乙個節點以上出現冗餘的問題。
接下來說說記憶體節點與磁碟節點在集群中的作用,在集群中的每個節點,要麼是記憶體節點,要麼是磁碟節點,如果是記憶體節點,會將所有的元資料資訊僅儲存到記憶體中,而磁碟節點則不僅會將所有元資料儲存到記憶體上, 還會將其持久化到磁碟。
在單節點 rabbitmq 上,僅允許該節點是磁碟節點,這樣確保了節點發生故障或重啟節點之後,所有關於系統的配置與元資料資訊都會重磁碟上恢復;而在 rabbitmq 集群上,允許節點上至少有乙個磁碟節點,在記憶體節點上,意味著佇列和交換器宣告之類的操作會更加快速。原因是這些操作會將其元資料同步到所有節點上,對於記憶體節點,將需要同步的元資料寫進記憶體就行了,但對於磁碟節點,意味著還需要及其消耗效能的磁碟寫入操作。
rabbitmq 集群只要求至少有乙個磁碟節點,這是有道理的,當其它記憶體節點發生故障或離開集群,只需要通知至少乙個磁碟節點進行元資料的更新,如果是碰巧唯一的磁碟節點也發生故障了,集群可以繼續路由訊息,但是不可以做以下操作了:
這是因為上述操作都需要持久化到磁碟節點上,以便記憶體節點恢復故障可以從磁碟節點上恢復元資料,解決辦法是在集群新增 2 臺以上的磁碟節點,這樣其中一台發生故障了,集群仍然可以保持執行,且能夠在任何時候儲存元資料變更。
啟動rabbitmq
docker run -d --hostname localhost --name myrabbit -p 15672:15672 -p 5672:5672 rabbitmq:3.6.15-management
引數說明:
啟動完成之後,使用:docker ps 檢視程式運**況。
使用:http://宿主ip:15672 訪問,使用者名稱密碼使用預設:guest/guest.(注意:映象帶management的才能進入介面)
RabbitMQ集群部署
第一步 獲取rabbitmq映象 docker pull rabbitmq management第二步 啟動mq docker run d hostname rabbit1 name myrabbit1 p 15672 15672 p 5672 5672 e rabbitmq erlang cook...
RabbitMQ集群部署
環境 ip主機名 作業系統 10.0.0.1 test1 centos7.2 10.0.0.2 test2 centos7.2 10.0.0.3 test3 centos7.2 一 安裝依賴環境。yum y install gcc glibc devel make ncurses devel ope...
Rabbitmq映象集群部署
位址 環境 兩台伺服器作為兩個節點,把node 003加入node 002 192.168.95.129 node 002 192.168.95.130 node 003 1.配置環境host,兩個節點的host都需要包含每個節點的資訊,資訊要一致。下面是在node 002中的操作。node 003...