RabbitMQ 默認的集群模式,也就是普通模式,最大的問題就在於存儲隊列完整數據的節點一旦宕機,
如果是非持久化隊列,則消息丟失;如果是持久化隊列+持久化消息,則必須等該節點恢復.
所以后來 RabbitMQ 開始支持隊列(完整數據)復制.比如在有5個節點的集群里,可以指定某個隊列的完整數據在2個節點上進行存儲,從而在性能與高可用之間取得一個平衡,這就是鏡像模式,它屬於 RabbitMQ 的HA方案.
鏡像模式解決了普通模式的問題,消息實體會主動在鏡像節點間同步,而不是在消費者獲取數據的時候臨時從其他節點拉取.當然,該模式的副作用也很明顯:
- 消息需要復制到每一個節點,對於持久化消息,網絡和磁盤同步復制的開銷都會明顯增加;
- 如果鏡像隊列數量過多,大量的消息進入,集群內部的網絡帶寬將會被這種同步通訊大大消耗掉.
所以鏡像模式適合在對可靠性要求較高的場合中使用.
綜上所述,鏡像模式的實質是鏡像隊列,一個隊列想做成鏡像隊列,需要先設置 policy,然后客戶端創建隊列的時候,RabbitMQ 集群根據“隊列名稱”自動設置是普通集群模式或鏡像模式.
下面我們通過管理后台將前面搭建的單機集群模式修改成鏡像模式.
搭建步驟
第一步
第二步
- Virtual host : 虛擬主機.
- Name : 策略名稱.
- Pattern : ^ 表示匹配所有隊列名稱.
- Apply to : 這里選擇的是同時應用到交換機和隊列.
- ha-mode 和 ha-params 見下表(原貼:http://www.ywnds.com/?p=4741)
然后我們可以看到,該虛擬主機下面的交換機和隊列都被打上了 test_mirror 標簽
+1 表示有1個鏡像節點.
進入該隊列詳情,可以清晰的看到 : 策略名稱,隊列的主節點以及鏡像節點等.
驗證功能
將就上一篇普通集群的代碼.
1.生產者連接到 node1 (5672) 發送消息,然后關閉 node1.
通過 node2 的管理后台可以看到隊列依然在.
但是有個細節,Node 從 rabbit1@node1 變成了 rabbit2@node2.
進入該隊列詳情,主節點已經變成了 rabbit2@node2 , 而鏡像節點是空.
2.消費者連接到 node2 接收消息
一切正常.
3.重新啟動 node1
可以看到,隊列的主節點沒有還原回去.
關於 HA sync mode,HA mirror promotion on shutdown,HA mirror promotion on failure 的測試
一.HA sync mode
該參數有兩個值:
- manual : 手動模式(默認值)
- automatic : 自動模式
手動模式下,新加入的節點不會同步老節點的隊列(及消息).測試如下:
1.我們先往"test_queue"隊列添加10條消息.
2.新增節點 node3
3.這時候我們再看管理后台,多了1個紅色的"+1",這個"+1"表示有一個節點沒有同步該隊列的數據.
我們進入該隊列查看詳情:
可以看到,有個"同步"的按鈕.我們可以手動同步.
如果我們把10條消息消費掉后,系統也會認為數據同步了,因為3個節點的數據一樣了.這時候紅色的"+1"就會消失,而之前的藍色"+1"變成了"+2".
自動模式的測試結果就不上圖了.
二.HA mirror promotion on failure
該參數有兩個值 :
when-synced
always (默認值)
默認值為 "always" ,如果隊列主節點發生故障,斷開連接或者從群集中刪除了,則最早的鏡像節點將被提升為新的主節點.但是在某些情況下,此鏡像節點可能沒有同步數據,這將導致數據丟失.
"when-synced" ,意味着當隊列主節點發生故障的時候,隊列將變得不可用,直到主節點恢復.如果隊列主節點永久丟失,除非將隊列刪除(同時會刪除其所有內容)並重新聲明,否則該隊列將永不可用;
這相當於通過降低安全性(將非同步鏡像節點升級為主節點),從而增加對隊列主機可用性的依賴,因為有時候隊列可用性比數據一致性更重要.
三.HA mirror promotion on shutdown
該參數也有兩個值 :
when-synced
(默認值)always
該參數的默認值為 "when-synced
", 如果隊列主節點關閉了(即顯式停止RabbitMQ服務或關閉操作系統),那么所有節點上的該隊列都將關閉.
"always" 意味着如果隊列主節點關閉了,可以提升一個未同步的節點為新的主節點,以避免數據丟失.
但是,如果 HA mirror promotion on failure 的值為 "when-synced" ,即使 HA mirror promotion on shutdown 的值為 "always" ,也不會提升未同步的節點.這意味着如果隊列主節點發生故障,隊列將在主節點恢復之前變為不可用.如果隊列主機永久丟失,除非將隊列刪除(也將刪除其所有內容)並重新聲明,否則該隊列將不可用.
測試
1.刪除之前創建的 node2,node3,只保留 node1;
2.刪除原來的策略,重新建了一個,並且 HA sync mode ,HA mirror promotion on failure 和 HA mirror promotion on shutdown 3個參數都未設定,即都使用默認值;
3.發送10條消息;
4.新建 node2,並加入集群.
目前該隊列情況如下:node1 是隊列主節點,並且 node2 尚未同步數據.
5.停止 node1, 即停止隊列主節點 ( rabbitmqctl stop_app )
這時候,該隊列變成了不可用,連接 node2 發送消息,接收消息都會失敗.
這個結果符合 HA sync mode ,HA mirror promotion on failure 和 HA mirror promotion on shutdown 3個參數默認值的預期.
6.恢復 node1 ( rabbitmqctl start_app ),進入該隊列詳情,點擊 按鈕,手動同步一下隊列數據,這時候,兩個節點的狀態是:node1 為隊列主節點,node2 已同步數據
7.再次關閉 node1.
從管理后台可以看見,該隊列依然可用,並且 node2 被提升成了隊列主節點.同樣符合 HA mirror promotion on failure 和 HA mirror promotion on shutdown 默認值的預期.
至於將 HA mirror promotion on shutdown 設為 "always ", HA mirror promotion on failure 設為 "when-synced" 的情況就不再測試了.
內存及硬盤控制(轉載)
一.內存控制
vm_memory_high_watermark 該值為內存閾值,默認為0.4.意思為物理內存的40%.40%的內存並不是內存的最大的限制,它是一個發布的節制,當達到40%時Erlang會做GC.最壞的情況是使用內存80%.如果把該值配置為0.將關閉所有的publishing.
Paging 內存閾值,該值為默認為0.5,該值為 vm_memory_high_watermark 的20%時,將把內存數據寫到磁盤.
如機器內存16G,當 RabbitMQ占用內存1.28G(16*0.4*0.2)時會把內存數據放到磁盤.
二.硬盤控制
當RabbitMQ的磁盤空閑空間小於50M(默認),生產者將被BLOCK.如果采用集群模式,磁盤節點空閑空間小於50M將導致其他節點的生產者都被block,可以通過 disk_free_limit 來對進行配置.
原貼:http://www.ywnds.com/?p=4741
HAProxy1.7.8 負載均衡
在某網站下載了一個 window 可以用的版本 haproxy-1.7.8
修改 haproxy.cfg 配置文件
global maxconn 15000 nbproc 1 daemon defaults mode tcp retries 3 option abortonclose maxconn 2000 timeout connect 300000ms timeout client 300000ms timeout server 300000ms log 192.168.1.5 local0 err listen RabbitMQ bind 192.168.1.5:8848 mode http balance roundrobin server node1 192.168.1.5:5672 weight 1 maxconn 2000 check inter 5s rise 1 fall 3 server node2 192.168.1.5:5673 weight 1 maxconn 2000 check inter 5s rise 1 fall 3 listen status bind 192.168.1.5:1188 mode http stats refresh 30s stats uri / stats auth admin:admin #stats hide-version stats admin if TRUE