失去连接后,Spring AWS SQS重新连接 [英] Spring AWS SQS Reconnect After Losing Connection

查看:87
本文介绍了失去连接后,Spring AWS SQS重新连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将Spring Cloud AWS(1.0.1.RELEASE)与Spring Boot结合使用来运行SQS使用者.该应用程序可以正常运行,但是当它失去网络连接时(例如,如果我在笔记本电脑上运行WIFI时关闭了WIFI),我会在控制台上看到错误,并且该应用程序永远无法恢复.它只是挂在那里,在网络可用后不会重新连接.我必须杀死它并提出来.我如何强迫它自行恢复?

I am using Spring Cloud AWS (1.0.1.RELEASE) with Spring Boot to run a SQS consumer. The application runs fine, but when it looses network connection (for instance if I switch my WIFI off on my laptop when it runs on it), I see errors on the console and the application never recovers. It just hangs there and does not reconnect after the network becomes available. I have to kill it and bring it up. How do I force it to recover by itself?

// Spring Boot entry point: 
public static void main(String[] args) {
    SpringApplication.run(MyConsumerConfiguration.class, args);
}

// Message Listener (A different class)
@MessageMapping(value = "myLogicalQueueName" )
public void receive(MyPOJO object) {

}

我在控制台上看到的错误:

The error I see at console:

线程"simpleMessageListenerContainer-1"中的异常com.amazonaws.AmazonClientException:无法执行HTTP请求:sqs.us-east-1.amazonaws.com在com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:473)在com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:297)在com.amazonaws.services.sqs.AmazonSQSClient.invoke(AmazonSQSClient.java:2422)在com.amazonaws.services.sqs.AmazonSQSClient.receiveMessage(AmazonSQSClient.java:1130)在com.amazonaws.services.sqs.AmazonSQSAsyncClient $ 23.call(AmazonSQSAsyncClient.java:1678)在com.amazonaws.services.sqs.AmazonSQSAsyncClient $ 23.call(AmazonSQSAsyncClient.java:1676)在java.util.concurrent.FutureTask.run(FutureTask.java:266)在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)在java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617)在java.lang.Thread.run(Thread.java:745

Exception in thread "simpleMessageListenerContainer-1" com.amazonaws.AmazonClientException: Unable to execute HTTP request: sqs.us-east-1.amazonaws.com at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:473) at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:297) at com.amazonaws.services.sqs.AmazonSQSClient.invoke(AmazonSQSClient.java:2422) at com.amazonaws.services.sqs.AmazonSQSClient.receiveMessage(AmazonSQSClient.java:1130) at com.amazonaws.services.sqs.AmazonSQSAsyncClient$23.call(AmazonSQSAsyncClient.java:1678) at com.amazonaws.services.sqs.AmazonSQSAsyncClient$23.call(AmazonSQSAsyncClient.java:1676) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745

推荐答案

我刚刚弄清了为什么在网络连接丢失后SQS无法重新连接的问题.

I just figured out the problem why SQS is not able to reconnect after network connection lost.

实际上,当前在 org.springframework.cloud.aws.messaging.listener.SimpleMessageListenerContainer.java

private class AsynchronousMessageListener implements Runnable {

    private final QueueAttributes queueAttributes;
    private final String logicalQueueName;

    private AsynchronousMessageListener(String logicalQueueName, QueueAttributes queueAttributes) {
        this.logicalQueueName = logicalQueueName;
        this.queueAttributes = queueAttributes;
    }

    @Override
    public void run() {
        while (isRunning()) {
            ReceiveMessageResult receiveMessageResult = getAmazonSqs().receiveMessage(this.queueAttributes.getReceiveMessageRequest());
            CountDownLatch messageBatchLatch = new CountDownLatch(receiveMessageResult.getMessages().size());
            for (Message message : receiveMessageResult.getMessages()) {
                if (isRunning()) {
                    MessageExecutor messageExecutor = new MessageExecutor(this.logicalQueueName, message, this.queueAttributes);
                    getTaskExecutor().execute(new SignalExecutingRunnable(messageBatchLatch, messageExecutor));
                } else {
                    break;
                }
            }
            try {
                messageBatchLatch.await();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

以上代码启动了一个新线程,该线程对SQS队列进行轮询以获取消息.断开网络连接后, getAmazonSqs().receiveMessage(this.queueAttributes.getReceiveMessageRequest())引发 UnknownHostException ,该代码未处理并导致线程终止.因此,稍后建立网络连接时,没有线程轮询队列以检索数据.

Above code spins up a new thread which does the polling to SQS queue to grab messages. Once network connection is dropped getAmazonSqs().receiveMessage(this.queueAttributes.getReceiveMessageRequest()) throws UnknownHostException, which is not handled in the code and causes thread termination. So when network connection is established later on, there is no thread polling the queue to retrieve the data.

为此,我已经向Spring提出了一个问题.以下是链接: https://github.com/spring-cloud/spring-cloud-aws/issues/82

I have already raised a issue with Spring for this. Following is the link: https://github.com/spring-cloud/spring-cloud-aws/issues/82

希望这能解释一切.

这篇关于失去连接后,Spring AWS SQS重新连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆