防止 spring-cloud-aws-messaging 尝试停止队列

Posted

技术标签:

【中文标题】防止 spring-cloud-aws-messaging 尝试停止队列【英文标题】:Prevent spring-cloud-aws-messaging from trying to stop the queue 【发布时间】:2020-02-24 08:24:55 【问题描述】:

我在 Spring Boot 项目中使用 spring-cloud-aws-messaging。 我在 AWS 中手动创建了 SQS 队列。

它的使用方式如下:

@SqsListener("$sqs.name.incoming")
public void listen(String message) 
    ...

它工作正常。但是当我在 IDE 中停止我的应用程序时,或者当 Spring Boot 测试完成时,它会尝试停止队列。它无法阻止它并最终超时。它抛出这个异常:

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.access$300(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$1.run(AbstractApplicationContext.java:945) ~[spring-context-5.1.10.RELEASE.jar:5.1.10.RELEASE]

这种等待会减慢应用程序或测试关闭速度。

我如何告诉spring-cloud-aws-messaging这是一个手动创建的队列,它不应该尝试关闭它?

【问题讨论】:

【参考方案1】:

它实际上并没有关闭 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;

【讨论】:

谢谢,github.com/spring-cloud/spring-cloud-aws/issues/504 有人回答。无论如何都接受你的回答,干杯。 酷。如果他们可以将默认值设置为 >20 以避免此异常,我提出了一个问题。 github.com/spring-cloud/spring-cloud-aws/issues/507 谢谢,这正是我所需要的! @AdrianM 你如何获得listenerContainer

以上是关于防止 spring-cloud-aws-messaging 尝试停止队列的主要内容,如果未能解决你的问题,请参考以下文章

PHP 怎么防止GET方式提交重复数据?

如何防止网站被*** 防止网站数据被***篡改

MyBatis怎么防止SQL注入

如何彻底防止SQL注入?

怎么防止网站被***和防止服务器被黑

在winform当中提交数据,如何防止重复提交?