防止 spring-cloud-aws-messaging 尝试停止队列
Prevent spring-cloud-aws-messaging from trying to stop the queue
我在 Spring 引导项目中使用 spring-cloud-aws-messaging
。
我在 AWS 中手动创建了 SQS 队列。
它的使用方式如下:
@SqsListener("${sqs.name.incoming}")
public void listen(String message) {
...
}
它工作正常。但是当我在 IDE 中停止我的应用程序时,或者当 Spring 引导测试完成时,它会尝试停止队列。它无法阻止它并最终超时。它抛出这个异常:
2019-10-29 15:40:07.949 WARN 10378 --- [ Thread-2] s.c.a.m.l.SimpleMessageListenerContainer : An exception occurred while stopping queue 'my-awesome-queue-name'
java.util.concurrent.TimeoutException: null
at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:204) ~[na:na]
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.waitForRunningQueuesToStop(SimpleMessageListenerContainer.java:161) ~[spring-cloud-aws-messaging-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.doStop(SimpleMessageListenerContainer.java:140) ~[spring-cloud-aws-messaging-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.cloud.aws.messaging.listener.AbstractMessageListenerContainer.stop(AbstractMessageListenerContainer.java:351) ~[spring-cloud-aws-messaging-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.stop(SimpleMessageListenerContainer.java:45) ~[spring-cloud-aws-messaging-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.cloud.aws.messaging.listener.AbstractMessageListenerContainer.stop(AbstractMessageListenerContainer.java:239) ~[spring-cloud-aws-messaging-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.stop(SimpleMessageListenerContainer.java:45) ~[spring-cloud-aws-messaging-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.doStop(DefaultLifecycleProcessor.java:238) ~[spring-context-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.access0(DefaultLifecycleProcessor.java:53) ~[spring-context-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.stop(DefaultLifecycleProcessor.java:377) ~[spring-context-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.stopBeans(DefaultLifecycleProcessor.java:210) ~[spring-context-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.onClose(DefaultLifecycleProcessor.java:128) ~[spring-context-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1018) ~[spring-context-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.run(AbstractApplicationContext.java:945) ~[spring-context-5.1.10.RELEASE.jar:5.1.10.RELEASE]
这种等待会减慢应用程序或测试关闭的速度。
我如何告诉 spring-cloud-aws-messaging
这是一个手动创建的队列并且它不应该尝试将其关闭?
它实际上并没有关闭 SQS 队列,而是关闭了正在轮询队列的 运行 任务。如 SimpleMessageListenerContainer.queueStopTimeout
.
中所定义,默认关闭超时为 10 秒
当任务正在轮询队列时,它会按照 SimpleMessageListenerContainerFactory.waitTimeOut
中的设置等待消息 1 到 20 秒。如果此轮询恰好大于 10 秒,则上述关闭将超时导致 TimeoutException
.
所以要解决这个问题,要么将 queueStopTimeout
增加到大于 20
@PostConstruct
public void setUpListenerContainer() {
listenerContainer.setQueueStopTimeout(25000);
}
或将投票 waitTimeOut
减少到小于 10。
@Bean
public SimpleMessageListenerContainerFactory simpleMessageListenerContainerFactory(AmazonSQSAsync amazonSqs) {
SimpleMessageListenerContainerFactory factory = new SimpleMessageListenerContainerFactory();
factory.setWaitTimeOut(5);
return factory;
}
我在 Spring 引导项目中使用 spring-cloud-aws-messaging
。
我在 AWS 中手动创建了 SQS 队列。
它的使用方式如下:
@SqsListener("${sqs.name.incoming}")
public void listen(String message) {
...
}
它工作正常。但是当我在 IDE 中停止我的应用程序时,或者当 Spring 引导测试完成时,它会尝试停止队列。它无法阻止它并最终超时。它抛出这个异常:
2019-10-29 15:40:07.949 WARN 10378 --- [ Thread-2] s.c.a.m.l.SimpleMessageListenerContainer : An exception occurred while stopping queue 'my-awesome-queue-name'
java.util.concurrent.TimeoutException: null
at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:204) ~[na:na]
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.waitForRunningQueuesToStop(SimpleMessageListenerContainer.java:161) ~[spring-cloud-aws-messaging-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.doStop(SimpleMessageListenerContainer.java:140) ~[spring-cloud-aws-messaging-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.cloud.aws.messaging.listener.AbstractMessageListenerContainer.stop(AbstractMessageListenerContainer.java:351) ~[spring-cloud-aws-messaging-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.stop(SimpleMessageListenerContainer.java:45) ~[spring-cloud-aws-messaging-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.cloud.aws.messaging.listener.AbstractMessageListenerContainer.stop(AbstractMessageListenerContainer.java:239) ~[spring-cloud-aws-messaging-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.stop(SimpleMessageListenerContainer.java:45) ~[spring-cloud-aws-messaging-2.1.3.RELEASE.jar:2.1.3.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.doStop(DefaultLifecycleProcessor.java:238) ~[spring-context-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.access0(DefaultLifecycleProcessor.java:53) ~[spring-context-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.stop(DefaultLifecycleProcessor.java:377) ~[spring-context-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.stopBeans(DefaultLifecycleProcessor.java:210) ~[spring-context-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.onClose(DefaultLifecycleProcessor.java:128) ~[spring-context-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1018) ~[spring-context-5.1.10.RELEASE.jar:5.1.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.run(AbstractApplicationContext.java:945) ~[spring-context-5.1.10.RELEASE.jar:5.1.10.RELEASE]
这种等待会减慢应用程序或测试关闭的速度。
我如何告诉 spring-cloud-aws-messaging
这是一个手动创建的队列并且它不应该尝试将其关闭?
它实际上并没有关闭 SQS 队列,而是关闭了正在轮询队列的 运行 任务。如 SimpleMessageListenerContainer.queueStopTimeout
.
当任务正在轮询队列时,它会按照 SimpleMessageListenerContainerFactory.waitTimeOut
中的设置等待消息 1 到 20 秒。如果此轮询恰好大于 10 秒,则上述关闭将超时导致 TimeoutException
.
所以要解决这个问题,要么将 queueStopTimeout
增加到大于 20
@PostConstruct
public void setUpListenerContainer() {
listenerContainer.setQueueStopTimeout(25000);
}
或将投票 waitTimeOut
减少到小于 10。
@Bean
public SimpleMessageListenerContainerFactory simpleMessageListenerContainerFactory(AmazonSQSAsync amazonSqs) {
SimpleMessageListenerContainerFactory factory = new SimpleMessageListenerContainerFactory();
factory.setWaitTimeOut(5);
return factory;
}