內存及磁盤告警

當內存使用超過配置的閾值或者磁盤剩餘空間低於配置的閾值時,RabbitMQ都會暫時阻塞(block)客戶端的鏈接(Connection)並中止接收從客戶端發來的消息,以此避免服務崩潰。與此同時,客戶端與服務端的心跳檢測也會失效。能夠經過rabbitmqctl list_connections命令或者web管理界面來查看它的狀態,被阻塞的Connection的狀態要麼是blocking,要麼是blocked。blocking對應於並不試圖發送消息的Connection,好比消費者關聯的Connection,這種狀態下的Connection能夠繼續運行。而blocked對應於一直有消息發送的Connection,這種狀態下的Connection會被中止發送消息。注意:在一個集羣中,若是一個Broker節點的內存或者磁盤受限,都會引發整個集羣中的全部Connection被阻塞。web

理想的狀況是當發送阻塞時能夠在阻止生產者的同時而又不影響消費者的運行。可是在AMQP協議中,一個信道上能夠同時承載生產者和消費者,同一個Connection中也能夠同時承載若干個生產者的信道和消費者的信道,這樣就會使得阻塞邏輯錯亂,雖然大多數時候並不會發生任何問題,可是仍是建議生產和消費的邏輯能夠分攤到獨立的Connection之上而不發生任何交集。客戶端程序能夠經過添加BlockedListener來監聽相應鏈接的阻塞信息。服務器

內存告警

RabbitMQ服務器會在啓動或者執行rabbitmqctl set_vm_memory_high_watermarkfraction命令時計算系統內存的大小。默認狀況下vm_memory_high_watermark的值爲0.4,即內存閾值爲0.4,表示當RabbitMQ使用的內存超過40%時,就會產生內存告警並阻塞全部生產者的鏈接。一旦告警被解除(有消息被消費或者從內存轉存到磁盤等狀況的發生),一切都會恢復正常。spa

默認狀況下將RabbitMQ所使用的內存的閾值爲40%,折並不意味着此時RabbitMQ不能使用超過40%的內存,這僅僅是限制了RabbitMQ的消息生產者。在最壞的狀況下,Erlang的垃圾回收機制會致使兩倍的內存消耗,也就是80%的使用佔比。操作系統

內存閾值能夠經過rabbitmq.config配置文件來配置,下面示例中設置了默認的內存閾值爲0.4:日誌

[
    {
        rabbit,{
            {vm_memory_high_watermark,0.4}
        }
    }
].

與此對應的rabbitmqctl系列的命令爲:code

rabbitmqctl set_vm_memory_high_watermark {fraction}

fraction對應上面配置中的0.4,表示佔用內存的百分比,取值爲大於等於0的浮點數。設置對應的百分比值以後,RabbitMQ中會打印服務日誌。blog

若是設置fraction爲0,全部的生產者都會被中止發送消息,這個功能能夠適用於須要禁止集羣間全部消息發佈的狀況。正常狀況下建議vm_memory_high_watermark取值在0.4到0.66之間,不建議取值超過0.7。rabbitmq

假設機器的內存爲4GB,那麼就表明RabbitMQ服務的內存閾值的絕對值爲4*0.4=1.6GB。若是是32位的Windows操做系統,那麼可用內存被限制爲2GB,也就意味着RabbitMQ服務的內存閾值的絕對值爲820MB左右。除了經過百分比的形式,RabbitMQ也能夠採用絕對值的形式設置內存閾值,默認單位是B。示例內存設置的絕對值爲1024MB(2014*1024*1024B):隊列

[
    {
        rabbit,{
            {vm_memory_high_watermark,{absolute,1073741824}}
        }
    }
].

純數字的配置可讀性比較差,RabbitMQ也提供了單位的形式,對應的示例以下:內存

[
    {
        rabbit,{
            {vm_memory_high_watermark,{absolute,1024MiB}}
        }
    }
].

可用的內存單位有:K或者KiB表示千字節,大小爲210B;M或者MiB表示兆字節,大小爲220B;G或者GiB表示千兆字節,大小爲230B。還有KB,大小爲103;MB,大小爲106;GB,大小爲109

與絕對值配置對應的rabbitmqctl系列的命令爲:

rabbitmqctl set_vm_memory_high_watermarker{fraction}

無論是這個命令仍是 rabbitmqctl set_vm_memory_high_watermarker{fraction} 命令,在服務重啓以後所設置的閾值都會失效,而經過配置文件的方式設置的閾值則不會在重啓以後失效,可是修改後的配置須要在重啓以後才能生效。

在某個Broker節點觸及內存並阻塞生產者以前,它會嘗試將隊列中的消息換頁到磁盤以釋放內存空間。持久化和非持久化的消息都會轉存到磁盤中,其中持久化的消息自己就在磁盤中有一份副本,這裏會將持久化的消息從內存中清除掉。

默認狀況下,在內存到達內存閾值的50%時會進行換頁動做,也就是說,在默認的內存閾值爲0.4的狀況下,當內存超過0.4的一半0.2時會進行換頁動做。能夠經過在配置文件中配置vm_memory_high_watermark_paging_ratio項修改此值,下面示例將換頁比率從默認的0.5修改成0.75:

[
    {
        rabbit,[
            {vm_memory_high_watermark_paging_ratio, 0.75},
            {vm_memory_high_watermark,{absolute, 1024MiB}}
        ]
    }
].

上面的配置會在RabbitMQ內存使用率達到30%時進行換頁動做,並在40%時阻塞生產者。

能夠將vm_memory_high_watermark_paging_ratio值設置爲大於1的浮點數,這種配置至關於禁用了換頁功能。

磁盤警告

當剩餘磁盤空間低於肯定的閾值時,RabbitMQ一樣會阻塞生產者,這樣能夠避免因非持久化的消息持續換頁而耗盡磁盤空間致使服務崩潰。默認狀況下,磁盤閾值爲50MB,這意味着當磁盤剩餘空間低於50MB時會阻塞生產者並中止內存中的換頁動做。這個閾值的設置能夠減少但不能徹底消除因磁盤耗盡而致使崩潰的可能性,好比在兩次磁盤空間檢測期間內,磁盤空間從大於50MB被耗盡到0MB。一個相對謹慎的作法是將磁盤閾值設置爲與操做系統所顯示的內存大小一致。

RabbitMQ會按期檢測磁盤剩餘空間,檢測的頻率與上一次執行檢測到的磁盤剩餘空間大小相關。正常狀況下,每10秒執行一次檢測,隨着磁盤剩餘空間與磁盤閾值的接近,檢測頻率會有所增長。當要達到磁盤閾值時,檢測頻率爲每秒10次,這樣有可能會增長系統的負載。

能夠經過在配置文件中配置disk_free_limit項來設置磁盤閾值。下面示例中將磁盤閾值設置爲1GB左右:

[
    {
        rabbit,[
            {disk_free_limit,{absolute, 1000000000}}
        ]
    }
].

這裏也可使用單位設置,單位的選擇能夠參照內存閾值的設置。

還能夠參考機器內存的大小爲磁盤的閾值設置一個相對的比值。好比將磁盤閾值設置爲與集羣內存同樣:

[
    {
        rabbit,[
            {disk_free_limit,{absolute, {mem_relative,1.0}}
        ]
    }
].

與絕對值和相對值這兩種配置對應的rabbitmqctl系列的命令爲:

rabbitmqctl set_disk_free_limit {disk_limit}

rabbitmqctl set_disk_free_limit mem_relative {fraction}

和內存閾值的設置命令同樣,Broker重啓以後將會失效。一樣,經過配置文件的方式設置閾值不會在重啓以後失效,可是修改後的配置須要在重啓以後才能生效,正常的狀況下,建議disk_free_limit.mem_relative 的取值爲1.0 到 2.0 之間。

參考:《RabbitMQ實戰指南》 朱忠華 編著;  

相關文章
相關標籤/搜索