rabbitmq腦裂以及監控添加

網絡分區的斷定node

RabbitMQ中與網絡分區的斷定相關的是net_ticktime這個參數,默認爲60s。在RabbitMQ集羣中的每一個broker節點會每隔 net_ticktime/4 (默認15s)計一次tick(若是有任何數據被寫入節點中,此節點被認爲被ticked),若是在連續四次某節點都沒有被ticked到,則斷定此節點處於down的狀態,其他節點能夠將此節點剝離出當前分區。將連續四次的tick時間即爲T,那麼T的取值範圍爲 0.75ticktime < T < 1.25ticktimeshell

默認狀況下,在45s,日誌出現網絡

=ERROR REPORT==== 16-Jul-2017::15:20:55 ===
Mnesia('rabbit@node1'): ** ERROR ** mnesia_event got {inconsistent_database, running_partitioned_network, 'rabbit@node2'}

當一個節點起來的時候,RabbitMQ會記錄是否發生了網絡分區,你能夠經過WebUI進行查看;app

RabbitMQ GUI上顯示

Network partition detected
Mnesia reports that this RabbitMQ cluster has experienced a network partition. There is a risk of losing data. Please read RabbitMQ documentation about network partitions and the possible solutions.

或者能夠經過rabbitmqctl cluster_status命令查看,若是查看到信息中的partitions那一項是空的,就像這樣ide

[{nodes,[{disc,['rabbit@node1', 'rabbit@node2']}]},
 {running_nodes,['rabbit@node2','rabbit@node1']},
 {cluster_name,<<"rabbit@node1">>},
 {partitions,[]}]

然而當網絡分區時,會變成這樣:this

[{nodes,  [{disc,  ['rabbit@node1','rabbit@node2']}]},
 {running_nodes,['rabbit@node1']},
 {cluster_name,<<"rabbit@node1">>},
 {partitions,  [{'rabbit@node1',['rabbit@node2']}]}]

當一個RabbitMQ集羣發生網絡分區時,這個集羣會分紅兩個或者多個分區,它們各自爲政,互相都認爲對方分區的節點已經down,包括queues,bindings,exchanges這些信息的建立和銷燬都處於自身分區內,與其它分區無關。若是原集羣中配置了鏡像隊列,而這個鏡像隊列又牽涉到兩個或者多個網絡分區中的節點時,每個網絡分區中都會出現一個master節點,若是分區節點個數充足,也會出現新的slave節點,對於各個網絡分區,彼此的隊列都是相互獨立的,固然也會有一些其餘未知的、怪異的事情發生。當網絡恢復時,網絡分區的狀態仍是會保持,除非採起一些措施去解決他.net

自動處理網絡分區日誌

RabbitMQ提供了4種處理網絡分區的方式,在rabbitmq.config中配置cluster_partition_handling參數便可,分別爲: code

    1. ignore
    1. pause_minority
    1. pause_if_all_down, [nodes], ignore|autoheal
    1. autoheal

默認是ignore: ignore的配置是當網絡分區的時候,RabbitMQ不會自動作任何處理,即須要手動處理中間件

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

pause_if_all_down: 在pause_if_all_down模式下,RabbitMQ會自動關閉不能和list中節點通訊的節點。語法爲{pause_if_all_down, [nodes], ignore|autoheal},其中[nodes]即爲前面所說的list。若是一個節點與list中的全部節點都沒法通訊時,自關閉其自身。若是list中的全部節點都down時,其他節點若是是ok的話,也會根據這個規則去關閉其自身,此時集羣中全部的節點會關閉。若是某節點可以與list中的節點恢復通訊,那麼會啓動其自身的RabbitMQ應用,慢慢的集羣能夠恢復

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

oscar cmp目前的配置以下:

rabbitmq.config

[
  {rabbit,
    [{cluster_nodes,
       {['rabbit@sh01-oscar-cmp-prod-rmq03','rabbit@sh01-oscar-cmp-prod-rmq01','rabbit@sh01-oscar-cmp-prod-rmq02'],ram }},
       {cluster_partition_handling,pause_minority}]},
       {kernel,[{net_ticktime, 60}]}
].

能夠看出使用的第二種方式

grafana添加報警規則

partitions Current Number of network partitions. 0 is ok. If the cluster is splitted the value is at least 2

由此能夠看出,partitions爲0時正常,若是集羣發生了分裂值至少爲2.故咱們能夠設置partitions值不爲0時報警

添加規則:

- alert: Rabbitmq_node_partitions
    expr: (rabbitmq_partitions{job="rabbitmq_monitor"}) != 0
    for: 2m
    labels:
      issuetype: "嚴重"
      sourcetype: "中間件"
    annotations:
      summary: "Instance {{ $labels.instance }} rabbitmq集羣節點故障: partitions"
      description: "{{ $labels.instance }} of job {{ $labels.job }} on {{ $labels.node }} rabbitmq集羣節點故障: partitions"
      referenceURL: "http://wiki.virtueit.net/display/CMDT/2.+Maintenance+Manual"
      recovered: "recovered"
相關文章
相關標籤/搜索