記憶體和磁盤警告
有兩種情況下,Rabbit MQ會停止讀取用戶端的連接配接socket,為了防止crash崩潰,這兩種情況是:
記憶體使用達到配置值
磁盤空間下降到配置值下
在這兩種情況下,伺服器會臨時阻塞連接配接—伺服器會暫停讀取釋出消息的用戶端的連接配接,連接配接心跳監控也會被禁用,在rabbitmqctl和管理查建中的所有網絡連接配接如果是blocking狀态,意味着他們沒有嘗試發送,是以可以繼續,如果是blocked狀态,意味着他們已經釋出了,現在需要被暫停。
叢集的警告
當運作Rabbit MQ叢集的時候,記憶體和磁盤警告是叢集範圍的,如果一個節點達到了限制,所有的節點都會阻塞連接配接。
這樣的意圖是停止生産者,但是讓消費者繼續不受影響,但是因為協定允許生産者和消費者在同一個Channel或者同一個連接配接的不同Channel上進行操作,這個邏輯是不完美的,在實踐中,不會産生任何問題,因為節流作為一種延遲被觀察,盡管如此,建議使用單獨的連接配接分别作為生産和消費。
檔案描述符耗盡 Running out of File Descriptors
當伺服器使用了作業系統配置設定給它的所有檔案描述符,它會拒絕用戶端連接配接,參考 “ 網絡指南 ” 學習更多。
當用戶端嘗試發送比伺服器接收消息快的時候,它們會進入瞬時的流控。
相關主題
記憶體如何限制工作
磁盤如何限制工作
用戶端可以檢測它們是否被阻塞
記憶體警告
Rabbit MQ伺服器在啟動和執行 rabbitmqctl set_vm_memory_high_watermark fraction 的時候會檢測機器上的RAM大小,預設情況下,Rabbit MQ使用記憶體超過40%的時候,會發出記憶體警告,阻塞所有釋出消息的連接配接,一旦警告解除(etc,伺服器paging消息到硬碟或者分發消息到消費者并且确認)服務會恢複正常。
預設的記憶體門檻值是40%,注意,這并不會阻止Rabbit MQ Server使用不到40%,僅僅意味着到達這個點的時候,釋出者會被扼殺,最壞的情況下,Erlang虛拟機會引起雙倍的記憶體使用(RAM的80%),強烈建議開啟作業系統的SWAP和Page Files。
32位架構每個程序的記憶體限制是2G,一般的64位(AMD或者Interleaving)每個程序允許256T,64位的Windows限制位8T,但是,即使在64位下,32的程序最大可用位址空間也是2G。
配置記憶體門檻值
可以通過編輯配置檔案來調整觸發流控的記憶體門檻值,下面是把門檻值設定位預設值0.4
vm_memory_high_watermark.relative = 0.4
下面是使用經典配置格式:
[{rabbit, [{vm_memory_high_watermark, 0.4}]}].
預設值0.4表示安裝的RAM或者可用虛拟位址空間兩者較小的40%,如果在一個32位機器上,你安裝了4G記憶體,4G的40%是1.6G,但是在32位Windows上,每個程序限制2G,所有門檻值實際上是2G的40%(820M).
另外,記憶體門檻值可以通過設定一個RAM絕對值來調整,下面的例子把門檻值設定位1073741824位元組(1024M)
vm_memory_high_watermark.absolute = 1073741824
相同的例子,但是使用記憶體機關
vm_memory_high_watermark.absolute = 1024MB
使用經典配置格式
[{rabbit, [{vm_memory_high_watermark, {absolute, 1073741824}}]}].
經典格式帶機關
[{rabbit, [{vm_memory_high_watermark, {absolute, "1024MiB"}}]}].
如果這個絕對值比安裝的RAM或者可用虛拟位址空間大,門檻值會被設定位較小的。
記憶體限制在Rabbit MQ Server啟動的時候,會被附加到RABBITMQ_NODEHOME.log日志上。
=INFO REPORT==== 29-Oct-2009::15:43:27 ===
Memory limit set to 2048MB.
在borker運作的時候也可以使用 rabbitmqctl set_vm_memory_high_watermark fraction 指令或者 rabbitmqctl set_vm_memory_high_absolute memory_limit指令,記憶體機關也可以使用,指令會立即生效,直到broker停止,如果broker重新啟動也要生效的話,相應的配置檔案也要改變,在執行此指令但是不改變門檻值的情況下,在具有熱交換的RAM系統裡面,門檻值可能會變化(因為記憶體總量變了。。)
禁用所有的釋出
設定門檻值為0,會立即觸發記憶體警告,阻塞所有的釋出連接配接(如果你希望禁用全局釋出,這是非常有用的),使用rabbitmqctl set_vm_memory_high_watermark 0.
有限的位址空間
當在64位機器上運作32位Erlang,位址記憶體是受限制的,伺服器會檢測并列印如下一條消息:
=WARNING REPORT==== 19-Dec-2013::11:27:13 ===
Only 2048MB of 12037MB memory usable due to limited address space.
Crashes due to memory exhaustion are possible - see
http:<em>//www.rabbitmq.com/memory.html#address-space</em>
記憶體警告不是完美的,盡管停止釋出通常會阻止記憶體的進一步使用,但還是有相當大的可能,其它一些東西會繼續提升記憶體的使用,通常,這種情況發生的時候,實體記憶體被耗盡,作業系統會開始交換,但是使用一個受限的位址空間,當超過這個限制的時候,會引起VM的幫虧。
是以強烈建議,在64位OS上運作64位Erlang虛拟機。
配置Paging門檻值
在broker達到high watermark阻塞釋出者之前,它會嘗試通過将隊列的内容page到磁盤來釋放記憶體,持久化和瞬時消息都會被page out.
預設情況下,在borker達到門檻值的50%時(預設記憶體門檻值是0.4,當0.2的記憶體被使用時)會發生這種情況。可以通過修改 vm_memory_high_watermark_paging_ration配置來進行修改:
vm_memory_high_watermark_paging_ratio = 0.75
使用經典配置:
[{rabbit, [{vm_memory_high_watermark_paging_ratio, 0.75},
{vm_memory_high_watermark, 0.4}]}].
上面的配置會在記憶體使用到04.*0.75=0.3的時候開始paging,在記憶體使用到0.4的時候阻塞釋出者。可以把vm_memory_high_watermark_paging_ratio設定的比1大,在這種情況下,隊列不會把内容page到磁盤,如果引起了記憶體警告,生産者會跟上面解釋的一樣被阻塞。
不識别的平台
如果Rabbit MQ Server不能識别你的系統,它會在RABBITMQ_NODENAME.log檔案中追加一條資訊,接着它會假設有1GRAM安裝。
=WARNING REPORT==== 29-Oct-2009::17:23:44 ===
Unknown total memory size for your OS {unix,magic_homegrown_os}. Assuming memory size is 1024MB
在這種情況下,vm_memory_high_watermark配置值會使用1G,在使用預設值0.4的時候,RabbitMQ的記憶體門檻值是410M,是以當記憶體使用超過410M的時候,它就會扼殺生産者,當Rabbit MQ不識别你的平台的時候,如果你有8GRAM,你希望門檻值設定位0.3在記憶體超過3G的時候來throttle生産者,
磁盤警告
當可用磁盤空間下降到配置值(預設為50M)之下,一個警告會觸發,所有的生産者會被阻塞,目标是避免填充整個磁盤,這會導緻節點的寫操作失敗,導緻Rabbit MQ中斷,為了減小填充磁盤的風險,所有進來的消息都會阻塞,在記憶體的壓力下,瞬時的消息,也會被page到磁盤,将繼續占用已經到達臨界值的磁盤空間,如果斯潘警告設定的太低,消息被快速page,有可能在兩次磁盤空間檢查之間填充完整個磁盤,導緻Rabbit MQ崩潰(10s),一種更保守的方法是将限制設定為與系統上安裝的記憶體量相同的限制(參見下面的配置)。
如果磁盤可用空間下降到配置值之下,警告會觸發,broker資料庫使用的磁盤或者分區的可用空間每10S就會檢測一次,用來決定是否觸發或者清楚警告,監控會從伺服器一啟動的時候就開始,在log file中會增加一條條目:
=INFO REPORT==== 23-Jun-2012::14:52:41 ===
Disk free limit set to 953MB
在不識别的平台上,監控會禁用,日志中列印消息:
=WARNING REPORT==== 23-Jun-2012::15:45:29 ===
Disabling disk free space monitoring

2019-12-02 14:14:37.008 [info] <0.374.0> Free disk space is insufficient. Free bytes: 49971200. Limit: 50000000
2019-12-02 14:14:37.008 [warning] <0.370.0> disk resource limit alarm set on node rabbit@iZwz9a2gqhk6zw8dbt0ok2Z.
**********************************************************
*** Publishers will be blocked until this alarm clears ***
**********************************************************
2019-12-02 14:31:07.853 [info] <0.374.0> Free disk space is sufficient. Free bytes: 30019989504. Limit: 50000000
2019-12-02 14:31:07.853 [warning] <0.370.0> disk resource limit alarm cleared on node rabbit@iZwz9a2gqhk6zw8dbt0ok2Z
2019-12-02 14:31:07.854 [warning] <0.370.0> disk resource limit alarm cleared across the cluster
2019-12-02 18:45:57.768 [error] <0.2758.0> Channel error on connection <0.1336.0> (172.18.211.58:35685 -> 172.18.211.59:5672, vhost: '/', user: 'syp'), channel 9:
operation basic.ack caused a channel exception precondition_failed: unknown delivery tag 1
2019-12-05 10:45:18.288 [info] <0.374.0> Free disk space is insufficient. Free bytes: 49905664. Limit: 50000000
2019-12-05 10:45:18.288 [warning] <0.370.0> disk resource limit alarm set on node rabbit@iZwz9a2gqhk6zw8dbt0ok2Z.
**********************************************************
*** Publishers will be blocked until this alarm clears ***
**********************************************************
2019-12-05 10:51:18.581 [info] <0.374.0> Free disk space is sufficient. Free bytes: 15076024320. Limit: 50000000
2019-12-05 10:51:18.581 [warning] <0.370.0> disk resource limit alarm cleared on node rabbit@iZwz9a2gqhk6zw8dbt0ok2Z
2019-12-05 10:51:18.582 [warning] <0.370.0> disk resource limit alarm cleared across the cluster

當在叢集中運作Rabbit MQ的時候,磁盤警告也是叢集範圍的,如果一個節點達到限制值之下,所有的節點都會阻塞進來的消息。
Rabbit MQ會定時檢查可用磁盤空間大小,這個頻率跟上次檢查時可用空間大小相關(以確定在磁盤将要耗盡時,磁盤警告能及時觸發),一般是每10S檢查一下磁盤空間,但是當接近限制值時,頻率會提升,當非常接近的時候檢測會1秒10此,它可能會影響系統的負載。
當可用磁盤空間下降到配置值之下,Rabbit MQ會阻塞生産者,阻止記憶體中的消息page到磁盤,這會減少磁盤被耗盡而導緻崩潰的風險,但是不能完全杜絕。特别是消息被快速page到磁盤,有可能在兩次磁盤檢查之間用完整個可用空間,保守的做法如下:
配置磁盤可用空間值
磁盤可用空間limit是通過disk_free_limit設定的,預設的50M是為了資料庫分區可用,配置檔案設定可用空間為1GB。
disk_free_limit.absolute = 1000000000
加上機關(KB,MB,GB)
disk_free_limit.absolute = 1GB
使用經典的格式
[{rabbit, [{disk_free_limit, 1000000000}]}].
帶機關
也可以設定磁盤可用空間跟機器上的記憶體相關,這個配置設定磁盤可用跟記憶體大小一樣
disk_free_limit.relative = 1.0
經典配置
[{rabbit, [{disk_free_limit, {mem_relative, 1.0}}]}].
這個配置可以在broker運作的時候通過指令rabbitmqctl set_disk_free_limit 大小
或者rabbitmq_disk_free_limit mem_relative 值來使用,這個指令會立即生效,直到broker停止,如果重新開機也要生效的話,需要修改配置檔案。
流控