检测闲置异步消费者

虽然高效,异步消费者的一个问题是检测其空闲状态——用户可能想要 如果一段时间内没有消息到达,则采取一些措施。spring-doc.cadn.net.cn

从1.6版本开始,现在可以配置监听器容器来发布ListenerContainerIdleEvent当一段时间过去消息未送达时。 当容器处于空闲状态时,每个事件都会发布idleEventInterval毫秒。spring-doc.cadn.net.cn

要配置此功能,设置idleEventInterval在集装箱上。 以下示例展示了如何在 XML 和 Java 中实现(对于SimpleMessageListenerContainer以及一个SimpleRabbitListenerContainerFactory):spring-doc.cadn.net.cn

<rabbit:listener-container connection-factory="connectionFactory"
        ...
        idle-event-interval="60000"
        ...
        >
    <rabbit:listener id="container1" queue-names="foo" ref="myListener" method="handle" />
</rabbit:listener-container>
@Bean
public SimpleMessageListenerContainer smlc(ConnectionFactory connectionFactory) {
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
    ...
    container.setIdleEventInterval(60000L);
    ...
    return container;
}
@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(rabbitConnectionFactory());
    factory.setIdleEventInterval(60000L);
    ...
    return factory;
}

在这些情况下,容器闲置时每分钟发布一次事件。spring-doc.cadn.net.cn

事件消耗

你可以通过实现来捕捉空闲事件ApplicationListener——要么是一般听众,要么是被缩小到只听众的听众 收到这个特定的活动。 你也可以使用@EventListener, 在 Spring Framework 4.2 中引入。spring-doc.cadn.net.cn

以下示例结合了@RabbitListener@EventListener合并为一个职业。 你需要明白应用监听器会接收所有容器的事件,所以你可能需要 如果你想根据哪个容器处于空闲状态采取具体作,可以检查监听器ID。 你也可以使用@EventListener 条件为此目的。spring-doc.cadn.net.cn

这些事件有四个属性:spring-doc.cadn.net.cn

以下示例展示了如何通过@RabbitListener以及@EventListener附注:spring-doc.cadn.net.cn

public class Listener {

    @RabbitListener(id="someId", queues="#{queue.name}")
    public String listen(String foo) {
        return foo.toUpperCase();
    }

    @EventListener(condition = "event.listenerId == 'someId'")
    public void onApplicationEvent(ListenerContainerIdleEvent event) {
        ...
    }

}
活动听众会看到所有容器的事件。 因此,在前面的例子中,我们根据听众ID缩小接收到的事件范围。
如果你想利用空闲事件停止lister容器,就不要打电话container.stop()在呼叫听者的线程中。 这样做总是会导致延迟和不必要的日志消息。 相反,你应该把事件交给另一个线程,这样可以停止容器。