检测空闲异步消费者
虽然效率很高,但异步消费者存在一个问题,那就是检测它们何时处于空闲状态——如果在一段时间内没有收到任何消息,用户可能希望采取一些措施。
从 1.6 版本开始,现在可以配置监听器容器,以便在经过一段时间没有消息传递时发布 ListenerContainerIdleEvent
。在容器空闲期间,每隔 idleEventInterval
毫秒发布一次事件。
要配置此功能,请在容器上设置 idleEventInterval
。以下示例显示了如何在 XML 和 Java 中执行此操作(对于 SimpleMessageListenerContainer
和 SimpleRabbitListenerContainerFactory
都是如此)
<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(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;
}
在所有这些情况下,容器空闲时每分钟发布一次事件。
事件消费
您可以通过实现 ApplicationListener
来捕获空闲事件——可以是通用监听器,也可以是仅接收此特定事件的监听器。您还可以使用 Spring Framework 4.2 中引入的 @EventListener
。
以下示例将 @RabbitListener
和 @EventListener
组合到一个类中。您需要理解,应用程序监听器会接收所有容器的事件,因此如果您希望根据哪个容器空闲采取特定操作,则可能需要检查监听器 ID。您也可以为此目的使用 @EventListener
的 condition
。
这些事件具有四个属性
-
source
:监听器容器实例 -
id
:监听器 ID(或容器 bean 名称) -
idleTime
:发布事件时容器空闲的时间 -
queueNames
:容器监听的队列的名称
以下示例显示了如何使用 @RabbitListener
和 @EventListener
注解创建监听器
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 缩小接收的事件范围。 |
如果您希望使用空闲事件来停止监听器容器,则不应在调用监听器的线程上调用 container.stop() 。这样做总是会导致延迟和不必要的日志消息。相反,您应该将事件传递给另一个线程,然后该线程可以停止容器。 |