1. 程式人生 > >RabbitMQ-模式、叢集、故障恢復

RabbitMQ-模式、叢集、故障恢復

MQ並不是在尋找一個訊息佇列,而是解決解耦問題的方法。本質為:解耦請求和操作; 從同步程式設計模型轉向非同步程式設計模型。

解決Rabbit相關問題 編碼與模式

解耦

  1. 分離請求和動作 – kfc訂單和取餐
  2. 提供擴充套件性: 不用負載均衡器
    1. 當處理服務無法負載時,可通過新增處理伺服器,而不用負載均衡,得益於RabbitMQ自動輪詢行為
  3. 零成本API:跨語言

發後即忘模型

關注任務的完成,但無須實時完成。用無須應答的訊息來觸發工作
匹配該模式的兩種一般型別任務:
    批處理: 針對大型資料集合的工作或轉換
    通知: 對發生事件的描述

用RabbitMQ實現RPC並等待響應

私有佇列和傳送確認:  訊息頭的reply_to欄位

叢集並處理失敗

RabbitMQ高可用性的兩種方法
    1. 設定Rabbit叢集
    2. 擴大程式的規模以提升效能
RabbitMQ 的內建叢集 的目標:
    允許消費者和生產者在Rabbit節點崩潰的情況下繼續執行。
    通過新增更多節點來線性擴充套件訊息通訊吞吐量。

叢集架構

RabbitMQ始終記錄的四種類型的內部元資料:
    佇列元資料 - 佇列名稱和他們的屬性
    交換器元資料 - 交換器名稱、型別和屬性
    繫結元資料  - 一張簡單的表格展示瞭如何將訊息路由到佇列
    vhost元資料 - 為vhost內的佇列、交換器、繫結提供名稱空間和安全屬性。

構建叢集式,RabbitMQ會追蹤新的元資料型別: 叢集節點位置,以及節點與已記錄的其他型別元資料的關係。
1. 叢集中的佇列:
只有佇列所有者節點知道有關佇列的所有資訊。所有其他非所有者節點只知道佇列的元資料和指向該佇列存在的那個節點的指標。
節點崩潰,叢集就與之失去了聯絡。新訊息也就丟失了。讓指定佇列重回叢集的唯一方式是 恢復故障節點。
預設情況下RabbitMQ不將佇列內容和狀態複製到所有節點原因:
a. 儲存空間
b. 效能: 訊息釋出時訊息會到每個叢集節點,都會觸發一次磁碟活動。
往Rabbit叢集新增更多的節點意味著你將擁有更多的節點來傳播佇列。 因為所有其他節點需要將接收到的該佇列的訊息傳遞給該佇列的所有者節點。
2. 分佈交換器


交換器只是名稱和佇列的繫結列表。通道按照繫結匹配的結果,將訊息路由到佇列。
建立新的交換器時,RabbitMQ會將查詢表新增到叢集中的所有節點上。這樣每個節點上的每條通道都可以訪問到新的交換器了。
當訊息已經在釋出通道上,但在路由完成之前節點發生故障的話,為避免生產者一直生產訊息,造成訊息丟失的風險。處理方式:
a. 使用amqp事務。
b. 使用傳送方確認模式來記錄連線中斷時尚未被確認的訊息。
3. 是記憶體節點還是磁碟節點
每個RabbitMQ節點,要麼是記憶體節點,要麼是磁碟節點。 記憶體節點將所有的佇列、交換器、繫結、使用者、許可權和vhost的元資料定義都儲存在記憶體中。而磁碟節點將元資料儲存在磁碟中。單節點系統只允許磁碟型別的節點。在叢集中,可選擇配置部分節點為記憶體節點。
RabbitMQ要求叢集中至少有一個磁碟節點。但是如果只有一個節點的話,如果這個節點崩潰了,叢集仍然可以保持執行。但是在該節點恢復前你無法更改任何東西。通常會在叢集中設定兩個磁碟節點。保證只要一個可用。
如果磁碟節點故障的話,記憶體節點重啟後就無法找到叢集了,所以當新增記憶體節點時,確保告知其所有的磁碟節點(記憶體節點唯一儲存 到磁碟的元資料資訊是叢集中磁碟節點的地址)

升級叢集節點

獨立系統中升級到最新版RabbitMQ很容易,只需解壓新版並執行即可,舊的資料會被保留。

叢集升級並不簡單,他的升級是半自動化的。如果簡單升級會抹去叢集上的所有配置和資料。
升級步驟:
    1 備份當前配置
    2 關閉所有生產者並等待消費者消費完佇列中的所有訊息。
    3 關閉節點,並解壓新版本到現有安裝目錄
    4 選擇其中一個磁碟節點作為升級節點
    5 其啟動時,該節點會持久化叢集資料升級到新版本
    6 啟動其他叢集磁碟節點,會獲取升級後集群資料
    7 啟動叢集記憶體節點。

映象佇列和保留訊息

RabbitMQ2.6.0之後有了內建的雙話冗餘選項:映象佇列; 映象佇列的主拷貝僅存在於一個節點上,並可在其他節點擁有從佇列拷貝。主節點不可用時,最老的從節點會被選舉成新的主佇列。
宣告並使用映象佇列
宣告:
queue_args={"x-ha-policy": "all"}
channel.queue_declare(queue="queuename", arguments=queue_args)

上面是在所有節點都建一個從節點。建議使用all
queue_args={"x-ha-policy" : "nodes",
"x-ha-policy-params" :["[email protected]"]}

這個會在指定節點上見從節點,或造成該節點掛了,就宣告不成功了。
工作原理:
通道將訊息傳送到映象佇列時,會將訊息同時傳送的從佇列。類似於fanout節點。
消費者取消。
對於消費但未返回確認的訊息,會重新入隊。

從故障中恢復

構建彈性訊息通訊基礎架構的兩部分:
1. 構建RabbitMQ叢集來確保可用性和效能
2. 編寫當節點發生故障時知道如何重連到叢集的應用程式。
通過負載均衡來處理重連到叢集:
1. 可以減少應用程式處理節點故障程式碼的複雜性
2. 確保在叢集中連結的平均分佈

將負載均衡器放置到Rabbit叢集的前端,你就可以讓它來處理節點選擇、故障伺服器檢測以及負載分佈這些複雜的事情了。
使用HAProxy做負載均衡

連線丟失和故障轉移
當故障轉移到新的節點時,你無法對叢集的狀態做任何假定。不管節點故障什麼時候發生,在檢測到故障並進行重連之後的首要任務是構造交換器、佇列和繫結,以便應用程式的運作。