1. 程式人生 > 其它 >關於RabbitMQ消費者預取訊息數量引數的合理設定

關於RabbitMQ消費者預取訊息數量引數的合理設定

根據RabbitMQ官方文件描述,可以通過“預取數量”來限制未被確認的訊息個數,本質上這也是一種對消費者進行流控的方法。
詳見:https://www.rabbitmq.com/consumer-prefetch.html#independent-consumers

需要針對具體的應用場景,適當增大或減小該引數值(預設值為0表示不限制),以提高消費者吞吐量和充分利用資源。
1.針對訂單類訊息,因為處理耗時很短,可以適當增大該引數值,這樣Broker在一次網路通訊中會盡可能多地推送一些資料給消費者,以提高消費吞吐量;
2.對於依賴CPU計算型的耗時任務,該引數值則不能設定過大,否則會出現訊息被分配後因為耗時等待一直無法確認而產生堆積,此時即使有別的消費者已經空閒也無法再被分配這些已經堆積的訊息,導致資源浪費。

RabbitMQ客戶端提供了相應設定方法:

// 設定預取訊息數量,預設值為0,不限流
channel.basicQos(10);

在Spring Boot框架中可以直接通過如下配置引數進行設定:

// listener型別為direct,設定預取訊息數量為10,預設值為250(在AbstractMessageListenerContainer中定義的常量:DEFAULT_PREFETCH_COUNT)
spring.rabbitmq.listener.direct.prefetch=10

落實到本專案中,線上曾出現過這樣的現象:K8S管理的Docker叢集中,當RabbitMQ中出現訊息堆積時,卻只有1個Docker例項的負載持續很高,而其他Docker例項都非常閒。這顯然不符合預期,應該大家都很忙才對。
經排查分析後得知:本專案的特點是每一個任務訊息都是CPU耗時型,如果消費者每次都獲取到多個任務訊息到本地,那麼就會出現即使其他消費者已經空閒了也無法為自己分擔任務的情形。

解決辦法:限制每次給每個消費者只分派一個任務訊息(prefetch=1),這樣如果某個消費者在處理任務時被“卡住”了,則不再分配新的任務給它,而是把剩下的任務訊息分配給那些已經空閒的消費者執行。


作者:程式設計隨筆
出處:http://www.cnblogs.com/nuccch/
宣告:本文版權歸作者和部落格園共有,歡迎轉載,但請在文章頁面明顯位置給出原文連線。