《RabbitMQ實戰指南》整理(五)RabbitMQ運維

一、集羣搭建

RabbitMQ集羣允許消費者和生產者在RabbitMQ單個節點奔潰的情況下繼續運行,它可以通過添加更多的節點來線性地擴展消息通信的吞吐量,當失去一個RabbitMQ節點時,客戶端能夠重新連接到集羣中的任何其他節點並繼續生產或消費。當集羣中的一個RabbitMQ節點奔潰時,該節點上的所有隊列上的消息也會丟失,RabbitMQ集羣中的所有節點都會備份所有的元數據信息,包括:①隊列的名稱及屬性;②交換器的名稱及屬性;③綁定關係數據;④vhost元數據。但是隻有隊列的所有者知道隊列的所有信息,所以會有隊列消息丟失的問題(可以通過如鏡像隊列解決)

1、多機多節點配置

多機多節點是指多臺機器組成一個RabbitMQ集羣。第一步需要配置各個節點的host文件,讓節點之間能夠識別對方的存在;第二步需要編輯RabbitMQ的cookie文件,確保各個節點的cookie文件使用的是同一個值,這裏的cookie相當於密鑰,各節點間通過密鑰互相認證;第三步配置集羣,可以通過rabbitmqctl工具配置,或者通過config文件配置,或者通過rabbitmq-autoCluster插件配置。

如果關閉了集羣中的所有節點,需要確保在啓動的時候最後關閉的節點是第一個啓動的,否則這個不是最後關閉的節點會等待最後關閉的節點啓動,等待時間是30秒,如果沒有等到這個先啓動的節點也會失敗,默認會重試10次30秒,如果重試還是失敗,當前節點會因失敗關閉自身的應用。如果最後一個關閉的節點最終由於某些異常而無法啓動,則可以通過rabbitmqctl forget_cluster_node命令來將此節點剔出當前集羣。如果集羣中的所有節點由於非正常因素如斷電而關閉,那麼集羣中的所有節點都會認爲還有其他節點在它後面,此時需要使用rabbitmqctl force_boot命令來啓動一個節點,之後集羣才能正常啓動

2、集羣節點類型

RabbitMQ中的每一個節點,要麼是內存節點,要麼是磁盤節點。內存節點是指將所有的隊列、交換器、綁定關係、用戶、權限和vhost的元數據定義都存儲在內存中,而磁盤節點則將這些存儲到磁盤中。單節點的集羣中只有磁盤類型的節點,而在集羣中可以配置部分節點爲內存節點,以獲得更高的權限。

如果集羣已經搭建好了,那麼可以使用rabbitmqctl change_cluster_node_type{disc,ram}命令來切換節點的類型,其中disc表示磁盤節點,而ram表示內存節點。

RabbitMQ要求在集羣中至少有一個磁盤節點,其他節點可以是內存節點,當節點加入或離開集羣時,它們必須將變更通知到至少一個磁盤節點,如果只有一個磁盤節點且其剛好崩潰了,那麼集羣可以繼續發送或接受消息,但是不能執行創建隊列、交換器、綁定關係、用戶、以及更改權限、添加或刪除集權節點的操作。當內存節點重新啓動後,它們會連接到預先配置的磁盤節點,下載當前集羣元數據的副本。爲確保集羣消息的可靠性,或者不確定使用哪個節點類型時,建議全部使用磁盤節點

3、剔除單個節點

有兩種常用的方式可以將節點剔除出集羣。第一種,在需要剔除的節點上執行rabbitmqctl stop_app或stop命令來關閉rabbitmq服務。之後在其他的節點上執行rabbitmqctl forget_cluster_node [email protected]剔除節點,這種方式適合當前節點不再允許RabbitMQ的情況。第二種方式是在需剔除的節點上執行rabbitmqctl reset命令

4、集羣節點的升級

如果RabbitMQ集羣由單獨的一個節點組成,只需關閉原來的服務,然後解壓新的版本運行即可。如果RabbitMQ集羣由多個節點組成,那麼可以參考單個節點的情形:①使用rabbitmqctl stop命令關閉所有節點的服務;②保存各個節點的Mnesia數據;③解壓新版本的RabbitMQ到指定的目錄;④指定新版本的Mnesia路徑爲步驟二中的數據路徑;⑤啓動新版本的服務,注意需要啓動原版本中最後關閉的節點

5、單機多節點配置

在一臺機器上部署多個RabbitMQ服務節點,需要確保每個節點都有獨立的名稱、數據存儲位置、端口號等。如果發生後續節點啓動報錯,大多數是由於配置問題,比如RabbitMQ Management插件配置了一樣的端口號等。啓動完各節點的服務之後,將節點添加到集羣中就可以了。在實際應用時,建議搭建多機多節點集羣,單機多節點可在實試驗時應用。

二、查看服務日誌

1、啓動RabbitMQ服務

啓動RabbitMQ服務可以使用rabbitmq-server-detached命令,這個命令會啓動Erlang虛擬機和RabbitMQ應用服務,rabbitmqctl start_app用來啓動RabbitMQ應用服務,而RabbitMQ應用服務啓動的前提時Erlang虛擬機是正常運行的。

在RabbitMQ中,日誌級別有none、error、warning、info、debug這5種,下一層級別的日誌輸出均包含上一層級別的日誌輸出,如warning級別的日誌包含warning和error級別的日誌。

2、關閉RabbitMQ服務

如果使用rabbitmqctl stop命令,會將Rrlang虛擬機一同關閉,而rabbitmqctl stop_app只會關閉RabbitMQ應用服務

3、其它

RabbitMQ種可以通過rabbitmqctl rotate_logs {suffix}命令來輪換日誌,比如:rabbitmqctl rotate_logs .bak會在日誌目錄下建立新的日誌文件,並將老的日誌添加.bak的方式區分保存。此外也可以通過程序化的方式查看服務日誌,設置相應的邏輯規則,將有用的日誌信息過濾並保存起來一邊後續的服務應用

三、單節點故障恢復

配置數據節點冗餘可以有效防止由於單點故障而降低整個集羣的可用性、可靠性。單點節點的故障主要包括:機器硬件故障、斷電、網絡異常、服務進程異常

  • 單點硬件故障包括機器硬盤、內存、主板等故障造成的死機,無法從軟件層面恢復。此時需要在集羣種的其它節點執行rabbitmqctl forget_cluster_nodes {nodename}命令來將故障節點剔除。如果之前有客戶端連接到故障節點,需要將故障節點的IP地址從連接列表種刪除,並讓客戶端重新連接以恢復整個應用
  • 如果遇到斷電故障,需要接通電源後重啓機器,此時節點上的RabbitMQ處於Stop狀態,此時需要從其它節點執行rabbitmqctl forgrt_cluster_nodes {nodeName}將節點從集羣種剔除,然後剔除當前故障RabbitMQ種的Mnesia數據,然後重啓RabbitMQ服務,最後將其作爲新節點加入到當前集羣種,否則可能會引起網絡分區
  • 網絡故障極易引發網絡分區,如發生網絡肆但未發生網絡分區,應第一時間關閉節點上的RabbitMQ進程,等待網絡恢復後重啓,如果已經發生了網絡分區,可以參考後續章節手動進行操作
  • 服務異常時,如RabbitMQ未終止,需要判斷風險是否可控,如不可控建議拋棄節點,一般情況下重新啓動服務進程即可

四、集羣遷移

RabbitMQ種的集羣遷移更多是用來解決集羣故障不可短時間內修復而將所有的數據、客戶端等遷移到新的集羣種,以確保服務的可用性。RabbitMQ集羣遷移包括元數據重建、數據遷移以及與客戶端連接切換

1、元數據重建

元數據重建是指在新的集羣種創建原集羣的隊列、交換器、綁定關係、vhost、用戶、權限和Prameter等數據信息,元數據重建後纔可以將原集羣種的消息及客戶端連接遷移過來。

手動創建元數據是十分低效的,可以通過Web管理頁面種的Download broker definitions按鈕下載集羣的元數據信息文件,之後再點擊Upload broker definitions按鈕上傳元數據文件,如果新集羣的數據與當前數據有衝突,對於交換器、隊列及綁定關係這類非可變對象會報錯,對於其它可變對象如Parameter、用戶等會被覆蓋,如果導入過程種失敗會只有部分數據加載成功

通過上述方法解決後會出現所有隊列落在當前節點的情況,一般有兩種方式解決,第一種是通過HTTP API接口在新集羣上創建相應的數據,另外一種是隨機連接集羣種不同節點的IP再創建隊列等信息。

2、數據遷移和客戶端連接的切換

一種方式是等待原集羣中的所有消息全部消費完成後再將連接斷開,再建立新的連接進行消費。但如果出現因服務故障無法等到的情況,則需要將原集羣中的數據消費出來,存入一個緩存區中,另一個線程讀取緩存區中的消息再發布到新的集羣中。RabbitMQ提供的Federation和Shovel插件即可實現類似的功能

3、自動化遷移

要實現集羣自動化遷移,需要在使用相關資源時就做好準備,與生產者消費者客戶端相關的是交換器、隊列及集羣的信息,當這3類資源發生改變時需要讓客戶端迅速感知,以便進行相應的處理。可以將相應的資源加載到Zookeeper的相應節點中,客戶在客戶端爲對應的資源節點加入watcher來感知變化。

五、集羣監控

1、通過HTTP API接口提供監控數據

RabbitMQ Management插件不僅提供了優秀的Web管理界面,還提供了HTTP API接口以供調用。集羣節點的信息可以通過/api/nodes接口來獲取;對於交換器而言的數據採集可以調用/api/exchange/vhost/name接口(操作默認主機時需要將“/”轉義成%2F否則會異常);隊列的數據採集接口爲/api/queues/vhost/name

2、通過客戶端提供監控數據

.NET中的RabbitMQ.Client的IModel也提供了ConsumerCount(string queue)和MessageCount(string queue)方法,可以分別獲取隊列中消費者的個數和查詢隊列中的消息個數

3、檢查RabbitMQ服務是否健康

爲判斷RabbitMQ是否具備服務外部請求的能力,可以使用AMQP協議來構建一個類似於TCP協議中的Ping檢測程序,當無法建立TCP協議層面的連接,獲取無法構建AMQP協議層面的連接,或者構建連接超時時,可以判定RabbitMQ服務處於異常狀態而無法正常爲外部應用提供相應的服務。

除了基於上述的行爲構建程序外還可以使用RabbitMQ Management插件提供的/api/aliveness-test/vhost的HTTP API接口,通過:①創建aliveness-test名稱的隊列來接受測試消息;②使用該隊列名稱作爲消息的路由鍵,將消息發往默認交換器;③到達隊列時就消費消息,否則報錯的方式來驗證RabbitMQ服務的健康性,它不會收到網絡問題的影響,且不會刪除創建的隊列,還能避免元數據事務對Mnesia數據庫造成的壓力

此外還可以使用/api/healthchecks/node和/api/healthchecks/node/node這兩個接口對當前節點或指定節點進行健康檢查,包括RabbitMQ應用、信道、隊列是否正常運行,是否有告警產生等

4、元數據管理與監控

管控的介入會降低消息中間件的靈活度,但是可以增強系統的可靠性,比如可以建立元數據審查系統來配置對應的元數據資源。這裏提供一種思路:所有的業務應用都需要通過元數據審查系統來申請創建相應的元數據信息,申請後進行審批,之後再在數據庫中存儲和在RabbitMQ集羣中相應的元數據,在數據庫和RabbitMQ集羣之間可以添加一個一致性校驗程序來檢測元數據不一致的記錄信息,上傳至監控管理系統,最後進行人工介入處理。元數據一致性檢測程序可以通過/api/definitions的HTTP API接口來獲取集羣的元數據信息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章