检测空闲的异步使用者
虽然效率很高,但异步使用者的一个问题是检测它们何时空闲 — 用户可能希望采用 如果一段时间内没有消息到达,则执行一些作。
从版本 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
— 要么是普通听众,要么缩小到只有
接收此特定事件。
您还可以使用@EventListener
,引入于 Spring Framework 4.2 中。
以下示例将@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 缩小接收的事件范围。 |
如果您希望使用 idle 事件来停止 lister 容器,则不应调用container.stop() 在调用侦听器的线程上。
这样做总是会导致延迟和不必要的日志消息。
相反,您应该将事件移交给其他线程,然后该线程可以停止容器。 |