Spring RabbitMQ:DirectMessageListenerContainer报MessageRejectedWhileStoppingException
问题
在启用优雅停机的Kubernetes集群中,Spring服务停机时出现如下日志:
time: Jul 10, 2025 @ 16:51:02.626 log: Successfully waited for consumers to finish. pod: xxx-6f4ddbdb98-66v79 time: Jul 10, 2025 @ 16:51:02.326 log: Failed to invoke listener pod: xxx-6f4ddbdb98-66v79 time: Jul 10, 2025 @ 16:51:02.326 log: Failed to invoke listener pod: xxx-6f4ddbdb98-66v79
堆栈跟踪:
org.springframework.amqp.rabbit.listener.exception.MessageRejectedWhileStoppingException: Message listener container was stopping when a message was received at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListenerAndHandleException(AbstractMessageListenerContainer.java:1532) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.lambda$executeListener$8(AbstractMessageListenerContainer.java:1518) at io.micrometer.observation.Observation.observe(Observation.java:498) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1518) at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer$SimpleConsumer.callExecuteListener(DirectMessageListenerContainer.java:1181) at org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer$SimpleConsumer.handleDelivery(DirectMessageListenerContainer.java:1138) at com.rabbitmq.client.impl.ConsumerDispatcher$5.run(ConsumerDispatcher.java:149) at com.rabbitmq.client.impl.ConsumerWorkService$WorkPoolRunnable.run(ConsumerWorkService.java:111) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.base/java.lang.Thread.run(Unknown Source)
已在Spring应用中配置优雅停机,且消息处理时长不超过默认停机时间(据了解DirectMessageListenerContainer无法配置该时长)。现咨询:该异常是错误还是消息重入队列的通知?若是后者,为何以错误级别日志输出?
回答
该异常是消息重入队列的通知,并非业务错误
当容器触发停机流程后,会立即停止接收新消息。此时若RabbitMQ仍推送消息过来,容器会抛出MessageRejectedWhileStoppingException,同时自动将消息退回队列,保证消息不会丢失,后续可用的Pod可正常消费这些消息。错误级别日志的原因
Spring AMQP将这类异常标记为错误级别,核心目的是提醒运维人员:停机过程中出现了消息接收的时序冲突。虽然不会影响消息最终的可靠性,但能帮助排查是否存在停机时机不合理、RabbitMQ消费者取消通知延迟等问题,属于"非预期但可恢复"场景下的告警式日志。额外说明
即便配置了优雅停机,DirectMessageListenerContainer的停机流程仍会遵循"停止接收新消息→等待正在处理的消息完成→关闭连接"的逻辑。日志中的Successfully waited for consumers to finish表明正在处理的消息已正常完成,报错的消息是停机流程启动后才收到的新消息,这类消息会被自动退回队列,无需额外干预。
内容的提问来源于stack exchange,提问作者shibel
相关产品推荐
相关产品推荐

