背景知识
配置 @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。
源码截图:
BU*生
更改代码前,没有使用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!