【问题标题】:How to pause/resume individual Spring JMS message listeners如何暂停/恢复单个 Spring JMS 消息侦听器
【发布时间】:2023-03-18 22:05:01
【问题描述】:

我的 Spring Boot JMS 应用程序正在使用来自多个 SQS 队列的消息。每个队列需要连接到不同的外部资源才能处理其消息。如果出现外部资源故障,我预计需要该资源的消费者会迅速将队列排空到 DLQ,这可不好玩。

当我的代码检测到其资源处于脱机状态时(例如,调用 REST 端点的通信异常),我需要能够独立挂起(暂停)每个消费者的消息侦听器。

我该怎么做?

在搜索对此的平台支持后,我发现 AbstractJmsListeningContainer(通过 Lifecycle 接口)支持 stop() 和 start() 方法,尽管它没有记录是否可以在 stop 调用之后调用 start。

我担心在我的多个 @JmsListener 注释消费者中似乎有一个共享实例;所以停止一个队列会阻止他们所有人,我不希望这样。

如何实现暂停单个消费者的最终目标?

我看到过使用多个 bean 定义的参考,如下所示:

@Bean
SimpleMessageListenerContainer container1(ConnectionFactory connectionFactory,
        MessageListenerAdapter listenerAdapter) {
// snip
}

@Bean
SimpleMessageListenerContainer container2(ConnectionFactory connectionFactory,
        MessageListenerAdapter listenerAdapter) {
// snip
}

...但从未见过任何解释说明如何以及何时使用一个与另一个。

【问题讨论】:

    标签: spring-boot spring-jms


    【解决方案1】:

    查看我对this question的回复。

    是的,您可以在stop() 之后拨打start()

    注意stop() 只停止线程;连接保持打开状态。

    如果您想关闭一切,请在stop() 之后调用shutDown(),然后在start() 之前调用initialize()

    但是,您不应该在侦听器线程上调用 stop() - 将其交给另一个线程并等待 isRunning() 为假。

    【讨论】:

    • 每个监听的组件都有一个 SimpleMessageListenerContainer 实例,还是在所有监听消息的组件之间共享?如果是后者,那我还是没有答案。
    • 正如我在我指出的答案中所说的那样。每个侦听器都会获得一个由其 id 注册的容器。
    • 在尝试了我的运行时环境后,我亲眼目睹了这一点。为每个侦听器分配一个不同的 id,然后我能够通过 getListenerContainer(container-id) 从 JmsListenerEndpointRegistry 的自动装配实例中获取 MessageListenerContainer。每个实例都是唯一的,停止一个实例只会停止该容器的入站消息。谢谢!
    猜你喜欢
    • 2019-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-27
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 1970-01-01
    相关资源
    最近更新 更多