背景知識
配置 @RabbitListener的concurrency屬性,會導致一個 @RabbitListener 配置 產生多個 consumers的情況。
不使用時,默認只在 隊列上產生一個 consumer。
配置concurrency屬性 會影響一個 ListenerContainer 的並發數量,按照源碼的解釋,被影響的 ListenerContainer 包括:
1、org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer
concurrentConsumers 屬性,默認為 1。
maxConcurrentConsumers 屬性,沒有默認值。
2、org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer
consumersPerQueue屬性,默認為1。
源碼截圖:
BUG產生
更改代碼前,沒有使用concurrency屬性,此時,隊列只有一個consumer(一個Java進程一個)。
因為當時 消費消息 的線程很慢(幾十秒~幾分鍾不等),要是一個一個地消費的話,有些消息就不能及時處理了。
為此,需要將消息消費更改為 並發消費模式。
改造前配置:
@RabbitListener(queues = {RabbitConfig.QUEUE_1})
RabbitMQ控制台的隊列 QUEUE_1 的 消費者,此時只有一個:
因為對RabbitMQ使用不熟悉,網上找了半天,哦,使用concurrency屬性可以實現需求啊!那就給 @RabbitListener添加這個屬性嘛!
改造后的配置:
@RabbitListener(queues = {RabbitConfig.QUEUE_1}, concurrency = "20")
此時,啟動服務時,隊列 QUEUE_1 下回出現 20個 消費者 :
好,任務完成,消息可以被並發消費了!
搞定!
若干天后,領導大聲喊我過去……
指着屏幕給我看,怎么這么多消費者!導致了@#¥@#¥@DS什么問題!(當時沒聽清楚吧,難道是導致 RabbitMQ服務器掛了?或者,服務器監控報警了?)
總之,問題很嚴重啊!
然后,還讓我改,怎么改?多線程啊!建立一個線程池,然后,每個線程處理一個消息。從而實現並發消費。
而不是,使用 @RabbitListener的concurrency屬性去實現。
好吧,建立線程池,然后,每收到一個消息,都 取一個線程去處理。
最后
問題最后解決了,可是,深深地被自己的技術水平給嚇到了!
還以為自己技術很好呢,結果,導致了這么大一個BUG!可怕啊!
做技術,還是要【嚴謹】【細致】【認真】才行。對於技術細節,要很好地把握才是!否則,誰知道會導致啥問題!
時過境遷,當痛定思痛,爭取以后的工作(生產環境)中……
再無BUG!