1. 程式人生 > >rabbitmq_cluster 網絡分區

rabbitmq_cluster 網絡分區

stat pau 由於 server 隊列 hand 穩定 rabbit follow

通常我們使用rabbitmq 做消息隊列,若我們是 cluster模式。若我們的網絡不穩定很容易造成網絡分區,監測是否發生網絡分區可以使用rabbitmq的ui來看,也可以用命令來檢測
rabbitmqctl cluster_status
若返回值為:
[{nodes,[{disc,[‘rabbit@node1‘, ‘rabbit@node2‘]}]},{running_nodes,[‘rabbit@node2‘,‘rabbit@node1‘]},
br/>{running_nodes,[‘rabbit@node2‘,‘rabbit@node1‘]},
{partitions,[]}]

則集群狀態為正常,若返回值為

[{nodes, [{disc, [‘rabbit@node1‘,‘rabbit@node2‘]}]},{running_nodes,[‘rabbit@node1‘]},
br/>{running_nodes,[‘rabbit@node1‘]},
{partitions, [{‘rabbit@node1‘,[‘rabbit@node2‘]}]}]

則表示rabbitmq發生網絡分區了。
此時我們要手動解決網絡分區。
一、最簡單的是我們重啟rabbitmq集群服務,這樣會造成以產生的消息隊列失去了消費者,即用戶的一些操作可能一直處於“轉圈”等待中。
二、
為了從網絡分區中恢復,首先需要挑選一個信任的分區,這個分區才有決定Mnesia內容的權限,發生在其他分區的改變將不被記錄到Mnesia中而直接丟棄。手動恢復網絡分區有兩種思路:

1.)停止其他分區中的節點,然後重新啟動這些節點。最後重啟信任分區中的節點,以去除告警。
2.) 關閉整個集群的節點,然後再啟動每一個節點,這裏需確保你啟動的第一個節點在你所信任的分區之中。
停止/啟動節點有兩種操作方式:

  1. rabbimqctl stop/ rabbitmq-server -detached
  2. rabbitmqctl stop_app/ rabbitmqctl start_app

此時我們也可以利用rabbimq自己的機制來解決網絡分區
RabbitMQ提供了4種處理網絡分區的方式,在rabbitmq.config中配置cluster_partition_handling參數即可,分別為:

  1. ignore
  2. pause_minority
  3. autoheal
    下面我們來一 一 贅述:
    1.ignore
    默認是ignore,如果不配置rabbitmq.config或者按如下配置:

    [
    {
    rabbit, [
    {cluster_partition_handling, ignore}
    ]

    }

    ].

ignore的配置是當網絡分區的時候,RabbitMQ不會自動做任何處理,即需要手動處理。

2、pause_minority

在rabbitmq.config配置文件中配置:

[
{
rabbit, [
{cluster_partition_handling, pause_minority}
]
}
].

當發生網絡分區時,集群中的節點在觀察到某些節點down掉時,會自動檢測其自身是否處於少數派(小於或者等於集群中一般的節點數)。少數派中的節點在分區發生時會自動關閉,當分區結束時又會啟動。這裏的關閉是指RabbitMQ application關閉,而Erlang VM並不關閉,這個類似於執行了rabbitmqctl stop_app命令。處於關閉的節點會每秒檢測一次是否可連通到剩余集群中,如果可以則啟動自身的應用,相當於執行rabbitmqctl start_app命令。

需要註意的是RabbitMQ也會關閉不是嚴格意義上的大多數。比如在一個集群中只有兩個節點的時候並不適合采用pause-minority模式,因為由於其中任何一個節點失敗而發生網絡分區時,兩個節點都會被關閉。當網絡恢復時,有可能兩個節點會自動啟動恢復網絡分區,也有可能還是保持關閉狀態。然而如果集群中的節點遠大於兩個時,pause_minority模式比ignore模式更加的可靠,特別是網絡分區通常是由於單個節點網絡故障而脫離原有分區引起的。不過也需要考慮2v2, 3v3這種情況,可能會引起所有集群節點的關閉。這種處理方式適合集群節點數大於2個且最好為奇數的情況。

3. autoheal
在autoheal模式下,當認為發生網絡分區時,RabbitMQ會自動決定一個獲勝的(winning)分區,然後重啟不在這個分區中的節點以恢復網絡分區。一個獲勝的分區是指客戶端連接最多的一個分區。如果產生一個平局,既有兩個或者多個分區的客戶端連接數一樣多,那麽節點數最多的一個分區就是獲勝的分區。如果此時節點數也一樣多,將會以一種特殊的方式來挑選獲勝分區。

配置示例如下:

[
{
rabbit, [
{cluster_partition_handling, autoheal}
]
}
].

rabbitmq_cluster 網絡分區