20120825 鄭昀
html
Q:MQ 們爲何要作生產者流量控制?
A:麻煩就在於:『像 Erlang 的虛擬機實現和設計上都沒有阻止用戶往一個進程的消息隊列裏扔消息,當消息的生產速度過快,超過進程的處理能力時,這些消息就堆積起來,佔用越來愈多的內存,最終致使VM崩潰。』
Q:我爲何要知道 MQ 在作生產者流量控制?
A:當你發現自家的 Producers 動輒被掛起或被阻塞時,你要知道該調 Consumer 的消費速率,仍是調 Memory Threshold of MQ 。
一,RabbitMQ 2.8.0+的流量控制
RabbitMQ 2.8.0+引入了一個新特性「internal flow control」。
至此 RabbitMQ 有三種流量控制:
1.1. Per-Connection Flow Control
是面向每個鏈接作的流量控制。
即,RabbitMQ 會主動阻塞(Block)那些發佈消息太快的鏈接(Connections),無需作任何配置。
若是鏈接被阻塞了,那麼它在 rabbitmqctl 控制檯上會顯示一個blocked的狀態。
RabbitMQ 的流量控制機制是基於信用證(Credit)的擁塞控制機制,後面
鄭昀會在附錄A中列出這個古老控制機制的詳細介紹。
1.2. Memory-Based Flow Control
RabbitMQ 會在啓動時檢測機器的物理內存數值。默認當 MQ 佔用 40% 以上內存時,MQ 會主動拋出一個內存警告並阻塞全部鏈接(Connections)。
你也能夠經過修改
rabbitmq.config 文件來調整內存閾值,默認值是 0.4,以下所示:
[{rabbit, [{vm_memory_high_watermark, 0.4}]}].
當 MQ 啓動時,該內存閾值也會寫入到 RABBITMQ_NODENAME.log 文件裏,以下所示:web
Memory limit set to 2048MB.
若是 MQ Server 不能識別你的系統,或者你在用 Windows 系統,那麼它會寫一個警告信息到
RABBITMQ_NODENAME
.log 文件裏,以下所示:
=WARNING REPORT==== 29-Oct-2009::17:23:44 ===
Unknown total memory size for your OS {unix,magic_homebrew_os}. Assuming memory size is 1024MB.
1.3. Disk-Based Flow Control
默認狀況,若是剩餘磁盤空間在 1GB 如下,RabbitMQ 主動阻塞全部的生產者。這個閾值也是可調的。
二,Apache ActiveMQ 的流量控制
2.1. ActiveMQ 的生產者流量控制的觸發條件有三個:
- 無論 mq 有無作持久化配置:
- !ActiveMQ所使用的內存到達 memoryUsage 配置值,默認值64MB;
- 若是 mq 作了持久化配置:
- !要打開了useCache開關,代表要將持久化消息緩存起來以便快速訪問,默認是True;
- !緩存在內存中消息總字節數到達 memoryLimit 配置值,默認值是1MB。
2.2. 觸發以後會致使:
生產者調用發送消息函數時被Stuck(卡住)。
(注:關鍵詞 activemq+stuck+producer 或 activemq+block+producer)
一,基於信用證(Credit)的擁塞控制機制apache
1993 年,ATM領域開始尋找一種能夠動態分配帶寬並防止信元丟失的傳輸機制。所以提出了ABR(Available Bit Rate,可用比特率)業務,ABR 不強制網絡爲其分配固定的帶寬,網絡經過反饋信息動態調整分配給每一個 ABR 鏈接的帶寬。不少專家都投入到 ABR 業務的擁塞控制規範研究上。緩存
基於 Credit 的方案由哈佛大學的H.T.Kung教授首先提出,採用鏈路級流控機制,以單一鏈路或虛電路VC做爲基本的控制單位。每條鏈路有一個信元發送節點(能夠是一個源端或一個交換節點)和一個接收節點(能夠是一個交換節點或一個目的端系統),每一個節點爲每一條VC維持一個排隊隊列,信元接收端監視每條VC的排隊隊列長度,決定發送端能夠發到VC上的信元數量(用信用證通知),信元發送端只能發送信用證值所容許的最大信元數量,若是隻有一條VC,則信用證的值應足夠大,以充分利用鏈路的帶寬。通常來講,信用證值應知足下列條件:信用證值大於等於 鏈路信元速率乘以鏈路來回程傳輸時延。網絡
圖6-17 給出了基於信用證擁塞控制機制的基本工做原理。信元接收方首先發送信用證到信元發送方,通知可用的緩衝區容量,發送方收到信用證以後,就可決定發送的信元數量。 函數
它的最大缺點是實現複雜,在每一對相鄰的節點之間都須要維持這一信用證機制,同時也增長了信元的時延。性能
二,RabbitMQ 是如何實現的spa
『實質上 RabbitMQ 就是經過監控每一個進程的mailbox,當某個進程負載太高來不及接收消息時,這個進程的mailbox就開始堆積消息。設計
當堆積到必定量時,就會阻塞住上游進程,讓其不得接收新消息。從而慢慢上游進程的mailbox也開始積壓消息。unix
到了必定的量又會阻塞上游的上游的進程接收消息,最後就會使得負責網絡數據包接收的進程阻塞掉,暫停接收數據。
這就有點像一個多級水庫,當下游水庫壓力過大時,上游水庫就得關閉閘門,使得本身的壓力也愈來愈大,須要關閉更上游的水庫閘門,直到關閉最最上游的閘門。』——http://ybbct.iteye.com/blog/
5,http://activemq.apache.org/producer-flow-control.html
6,http://working-with-activemq.blogspot.com/2012/05/performance-improvements.html
7,http://stackoverflow.com/questions/5291679/activemq-topic-flooding
8,http://www.huaishao8.com/tag/activemq