【问题标题】:Spring AMQP ListenerContainer lifecycle managementSpring AMQP ListenerContainer 生命周期管理
【发布时间】:2015-11-21 16:08:18
【问题描述】:

我们在基于 Spring 的 Web 应用程序中使用 Spring AMQP 连接到 RabbitMQ。

当我们在应用程序上下文中将侦听器容器声明为 bean(使用 rabbit:listener-container)时,它们的生命周期由 Spring 管理。

如果我们在@PostConstruct 方法内的组件中声明一个侦听器容器,或者我们创建一个具有类org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer 的bean 作为原型作用域bean,那么我们必须管理生命周期,即启动和停止侦听器-自己装容器。

我的问题是,如果我们在 @PostConstruct 方法中声明新的队列、绑定和侦听器容器,只需在相应的 @PreDestroy 方法中调用 listener.stop/shutdown/destroy 方法就足以正常关闭?否则我需要做什么?

注意:我猜我不需要为 @PostContruct 中创建的新队列和绑定做任何事情,但如果您也为我确认这一点,我将非常高兴。

【问题讨论】:

    标签: spring spring-amqp spring-rabbit


    【解决方案1】:

    我不建议在@PostConstruct 方法中启动侦听器容器或声明队列/绑定;当时的情况只是半生不熟。它可能有效,但不建议在初始化上下文时执行此类操作。

    最好实现SmartLifecycle 并在start()/stop() 方法中启动/停止它们。

    然后,容器生命周期将由 spring 上下文间接管理。

    您还可以通过将 bean 置于一个阶段来精确控制 bean 何时启动/停止。

    【讨论】:

    • 感谢您的回答。我将实现SmartLifecycle 接口而不是使用@Postconstruct/@PreDestroy。此外,只需在侦听器容器上调用 stop 即可优雅地清理所有内容,对吧?队列和绑定什么都不做?
    • 这取决于你的意思是清理。如果您将队列/交换声明为自动删除,它们将在容器停止时自动消失;队列首先被删除;当没有队列时,交换被删除。如果您希望它们在调用之间保留(以避免丢失消息),则无需清理;下次声明它们将是幂等的,您将获取上次调用中剩余的任何消息。如果您没有声明它们自动删除并且您希望它们消失,那么您需要在停止容器后删除它们(例如使用 RabbitAmin)。
    • 请注意,当您断开连接时,自动删除可能会出现问题。重新建立连接时,会自动重新声明 Spring 声明的队列等。由于出于某种原因您自己滚动,因此您需要在连接失败后处理重新声明自动删除项目。通常让 Spring 为您处理事情比自己做要容易得多。