rabbitmq 學習與實踐分享之網絡分區

前言

上一篇文章簡單的介紹了一下經過docker搭建rabbitmq集羣的過程。本文主要介紹一 下rabbitmq 集羣針對網絡分區的應對策略,主要針對如下幾個問題展開:node

  • 什麼是網絡分區?
  • 爲何會出現網絡分區?如何模擬?
  • 網絡分區對rabbitmq的消費者,生產者有什麼影響?
  • rabbitmq 如何應對網絡分區?

一.什麼是網絡分區?

在分佈式系統中,不一樣的節點分佈在不一樣的子網絡中,因爲一些特殊的緣由,這些子節點之間出現了網絡不通的狀態,但他們的內部子網絡是正常的。從而致使了整個系統的環境被切分紅了若干個孤立的區域,這就是網絡分區。針對rabbitmq 而言,出現網絡分區時,處於子網中的節點會認爲不處於自身分區的節點都down了,針對交換器,隊列,綁定關係等操做都只對當前分區有效。docker

二.爲何會出現網絡分區?

出現網絡分區的緣由有不少,好比網卡故障,網絡閃斷等等致使子網間網絡不通。rabbitmq 內部節點默認會經過25672端口進行彼此間信息交換,若是每隔1/4的net_ticktime 時間進行一次應答時,連續4次出現應答不上,則會認爲彼此間網絡不通,就會出現部分節點被剝離出當前分區,進而造成網絡分區;網絡

默認配置文件第361行: %% {net_ticktime, 60} 
複製代碼

docker 模擬網絡分區

首先假設以及搭建起了由myrabbit1,myrabbit2,myrabbit3 3個節點構成的集羣,以下所示:集羣中包含3個disc 類型的節點運維

root@rabbit3:/# rabbitmqctl cluster_status
  Cluster status of node rabbit@rabbit3 ...
 [{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]}]},
 {running_nodes,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]},
 {cluster_name,<<"rabbit@rabbit3">>},
 {partitions,[]},
 {alarms,[{rabbit@rabbit1,[]},{rabbit@rabbit2,[]},{rabbit@rabbit3,[]}]}]
複製代碼

經過docker pause 命令暫停其中的一個docker進程,過一段時間以後再unpause 該容器,模擬net_ticktime 超時.tcp

如圖所示發現出現了2個分區,經過rabbitmq 的管理界面也可以感知到分區的存在,如圖所示:

三.網絡分區出現對消息的生產者和消費者會產生什麼影響呢?

分2種狀況討論:分佈式

  • 不存在鏡像隊列
  • 存在鏡像隊列

不存在鏡像隊列的狀況:

場景1:

生產者客戶端 節點名稱 交換器 綁定key 隊列 client1 nodel ex key1 queue1 client2 node2 ex key2 queue2spa

說明一下:   
> 這種場景表示生產者客戶端1 鏈接到節點1上,經過路由key1 發送消息的exchange中,最終消息被路由到queue1(queue1也是定義在node1上);
> 生產者客戶端2 鏈接到節點2上,經過路由key2 發送消息的exchange中,最終消息被路由到queue2(queue2也是定義在node2上)
複製代碼

在這種狀況下,不論是否出現網絡分區,對生產者,消費者而言都不會有影響;code

場景2:

說明:仍是上面的配置,生產者客戶端1 仍是連到節點1上,queue1也仍是在節點1上, 可是客戶端發送消息的時候,採用的路由鍵是key2, 也就是說消息會被路由到node2上的隊列queue2裏。同理,生產者客戶端2 仍是連在節點2上,queue2也仍是在節點2上,可是消息發送的時候是經過key1路由到nodel1 上的queue1裏。 
複製代碼

這種場景下出現網絡分區就有問題了:cdn

出現網絡分區以後,node1和node2 連不通了,這時候對於生產者客戶端而言:發送出去的消息找不到對應的綁定隊列了,消息會被退回或者丟棄; 對於消費者而言,消息消費以後,向對應的broker 發送確認ack消息的時候,也會發現找不到相應的節點了,這個時候消息消費端的確認機制也會有問題,可能會收到重複消息。blog

我的理解:出現這種問題的根本緣由仍是在於:rabbitmq的集羣的節點間只是會同步元數據信息,消息只是放在對應的宿主隊列裏。

存在鏡像隊列的狀況:

有鏡像隊列的狀況,複雜的多,由於出現網絡分區以後,對於鏡像隊列涉及到主從晉升,這塊的場景後面再進一步詳細分析。

四. rabbitmq 如何應對網絡分區:

rabbitmq 針對網絡分區提供了幾種配置:

[
    {rabbit,
       [
        {tcp_listeners,[5672]},
        {cluster_partition_handling, ignore}
       ]
    }
 ].
複製代碼

配置項分爲如下幾種:

  • ignore 默認類型,不處理。要求你所在的網絡環境很是可靠。當出現網絡分區的時候須要人工介入。

  • pause_minority:
    rabbitmq節點感知集羣中其餘節點down掉時,會判斷本身在集羣中處於多數派仍是少數派,也就是判斷與本身造成集羣的節點個數在整個集羣中的比例是否超過一半。若是是多數派,則正常工做,若是是少數派,則會中止rabbit應用並不斷檢測直到本身成爲多數派的一員後再次啓動rabbit應用。注意:這種處理方式集羣一般由奇數個節點組成。

  • autoheal 你的網絡環境多是不可靠的。你會更加關心服務的可持續性,而非數據完整性。 通常針對包含2個節點的集羣,當網絡分區恢復後,rabbitmq各分區彼此進行協商,分區中客戶端鏈接數最多的爲勝者,其他的所有會進行重啓,恢復到同步狀態。

總結

本文只是簡單介紹了一下rabbitmq的網絡分區,以及相應的配置策略。因爲更多的偏運維層面,實踐經驗較少,可能談的不夠深刻,後續在實踐中通過沉澱後再進一步補充。

參考書籍《rabbitmq 實戰》

相關文章
相關標籤/搜索