當乙個集**生網路分割槽時,集群會分為兩個部分或者更多,它們各自為政,互相都認為對方分區內的節點已經掛了,包括佇列、交換器及繫結等元資料的建立和銷毀都處於自身分區內,與其他分割槽無關。分割槽的引入是為了配合rabbitmq的資料一致性複製原理。一般情況下,網路分割槽都是由於單個節點的故障引起的,且通常會形成乙個大分割槽和乙個單節點分割槽,如果配置了映象,那麼可以在不影響服務可用性的情況下從網路分割槽的情形下得以恢復。
rabbitmq集群內兩兩節點之間會有資訊互動,如果某節點出現網路故障或是埠不同,則會使與此節點的互動出現中斷,經過超時判定後,會判定網路分割槽。網路分割槽的判斷與net_ticktime引數息息相關,其預設值為60。集群內部每個節點間會每隔四分之一net_ticktime記一次應答,如果任何資料被寫入節點中,則此節點會被認為已經被應答了,如果連續4此沒有應答,則會判定此節點已下線,其餘節點可以將此節點剝離出當前分割槽。
網路分割槽的一些細節會儲存在mnesia資料庫中,當mnesia認定發生了網路分割槽,則會被記錄在rabbitmq服務日誌中。除了服務日誌外還有以下三種方法可以判定是否出現了網路分割槽:
對於未配置映象的集群,網路分割槽發生之後,佇列也會隨著宿主節點而分散在各自的分割槽中。對於訊息傳送方而言,可以成功傳送訊息,但是會有路由失敗的情況,需要配合mandatory等機制保障訊息的可靠性,對於訊息消費方而言,可能會出現不可預知的現象,比如已消費訊息ack會失效。網路分割槽發生後,客戶端與某分割槽重新建立通訊鏈路,其分割槽中如果沒有相應的佇列程序,則會有異常報出。如果從網路分割槽中恢復,資料不會丟失,但是客戶端會重複消費
網路分割槽的發生會引起訊息的丟失,解決辦法為訊息傳送端需要具備basic.return的能力,其次在檢測到網路分割槽之後,需要迅速地掛起所有生產者程序,之後連線分割槽中的每個節點消費分割槽中所有的佇列資料,在消費完之後再處理網路分割槽,最後從網路分割槽中恢復之後再恢復生產者程序。整個過程可以最大程度上保證網路分割槽之後的訊息的可靠性。需要注意的是整個過程中會有大量的訊息重複,消費客戶端需要做好相應的冪等性處理。也可以將所有舊集群資源遷移到新集群來解決這個問題。
為了從網路分割槽中恢復,需要挑選乙個信任分割槽,該分割槽具有決定mnesia內容的許可權,發生在其它分割槽的改變將不會被記錄到mnesia中而被丟棄。挑選完後重啟非信任分割槽中的節點,如果還有網路分割槽的告警,緊接著重啟信任分割槽中的節點。這個有三個要點需要注意:
rabbitmq提供了三種自動處理網路分割槽的方法:pause-minority模式,pause-if-all-down模式和autoheal模式,預設是ignore,即不自動處理網路分割槽,其修改對應config檔案中的cluster_partition_handling屬性
在此模式下,當發生網路分割槽時,集群中的節點在觀察到某些節點下線時,會自動檢測其是否屬於少數派(分割槽中的節點小於等於集群中一般的節點數),rabbitmq會自動關閉這些節點的運作,以滿足可用性,當分割槽結束時又會啟動。處於關閉的節點會每秒檢測一次是否可以連通到剩餘集群中,如果可以則啟動自身的應用。
rabbitmq也會關閉不是嚴格意義上的大多數,如果集群中只有兩個節點,其中任一節點關閉,另乙個節點都會被關閉,所以pause-minority模式適用於集群節點數大於2個的時候。但如果出現2v2、3v3類的對等節點數的分割槽情況,所有節點上的rabbitmq應用都會被關閉
該模式下,rabbitmq集群中的節點在所配置的列表中的任何節點都不能互動時則會關閉。該模式下有兩種配置,ignore和autoheal,當出現對等節點數分割槽的情況,ignore不會自動處理,autoheal則可以處理這種情形
在該模式下,rabbitmq會自動決定乙個獲勝的分割槽,然後重啟不在這個分割槽中的節點來從網路分割槽中恢復。獲勝分割槽是指客戶端連線最多的分割槽,如果連線客戶端相同則選擇節點數較多的乙個分割槽,如果節點數相同,則以節點名稱的字典順序來判斷。該模式在判定出節點下線時不做動作,要等到網路分割槽恢復時,在判定出網路分割槽之後才會有相應的動作,即重啟非獲勝分割槽中的節點。
需要注意,在此模式下,如果集群中有節點處於非執行狀態,那麼當發生網路分割槽時,將不會有任何自動處理的動作
ignore:網路分割槽發生時,不做任何動作,需要人工處理;
pause-minority:對等分割槽的處理不夠優雅,一般用於非跨機架、奇數節點數的集群中;
pause-if-all-down模式:對於受信任節點的選擇較為考究
autoheal:可以應對各個情形下的網路分割槽,但是如果集群中有節點處於非執行狀態,則此模式會失效
RabbitMQ 實戰指南 一 延遲佇列
延遲佇列中儲存延遲訊息,延遲訊息是指當訊息被傳送到佇列中不會立即消費,而是等待一段時間後再消費該訊息。延遲佇列很多應用場景,乙個典型的應用場景是訂單未支付超時取消,使用者下單之後30分鐘內未支付成功,則把訂單取消。rabbitmq 本身沒有直接支援延遲佇列的功能,但是可以通過過期時間ttl和死信佇列...
RabbitMQ 實戰指南 一 死信佇列
dlx,全稱為 dead letter exchange,可以稱之為死信交換器。當訊息在乙個佇列中變成死信 dead message 之後,它能被傳送到另乙個交換器中,這個交換器就是dlx,繫結dlx的佇列就稱之為死信佇列。dlx 也是乙個正常的交換器,和一般的交換器沒有區別,它能在任何的佇列上被指...
RabbitMQ使用者指南(RabbitMQ C)
rabbitmq c是乙個用於c語言的,與amqp server進行互動的client庫,amqp協議為版本0 9 1。rabbitmq c與server進行互動前需要首先進行login操作,在操作後,可以根據amqp協議規範,執行一系列操作。介面描述 amqp connection state t...