java - Amazon SQS 长轮询不返回所有消息

标签 java amazon-web-services queue long-polling amazon-sqs

我需要在 1 次读取中读取我的 Amazon SQS 队列中的所有消息,然后根据创建的时间戳对其进行排序并对其执行业务逻辑。

为了确保检查所有 SQS 主机的消息,我启用了长轮询。我这样做的方法是将队列的默认等待时间设置为 10 秒。 (任何大于 0 的值都将启用长轮询)。

然而,当我尝试读取队列时,它仍然没有给我所有的消息,我不得不多次读取才能获得所有消息。我什至通过每个接收请求的代码启用了长轮询,但仍然没有用。以下是我正在使用的代码。

AmazonSQSClient sqsClient = new AmazonSQSClient(new ClasspathPropertiesFileCredentialsProvider());
sqsClient.setEndpoint("sqs.us-west-1.amazonaws.com");
String queueUrl = "https://sqs.us-west-1.amazonaws.com/12345/queueName";
ReceiveMessageRequest receiveRequest = new ReceiveMessageRequest().withQueueUrl(queueUrl).withMaxNumberOfMessages(10).withWaitTimeSeconds(20);
List<Message> messages = sqsClient.receiveMessage(receiveRequest).getMessages();

我在队列中有 3 条消息,每次运行代码时都会得到不同的结果,有时我会收到所有 3 条消息,有时只会收到 1 条消息。我将可见性超时设置为 2 秒,只是为了消除消息变得不可见作为在阅读中看不到它们的原因。 这是短轮询的预期行为。长轮询应该消除多重轮询。我在这里做错了什么吗?

谢谢

最佳答案

Long polling is supposed to eliminate multiple polls

不,长轮询应该在消息实际可用时消除大量空轮询和错误的空响应。 SQS 中的长轮询不会坐下来等待最大等待时间,只是为了寻找更多要返回的东西,或者一旦找到东西就继续搜索。 SQS 中的长轮询只会等待足够长的时间才能找到东西:

Long polling allows the Amazon SQS service to wait until a message is available in the queue before sending a response. So unless the connection times out, the response to the ReceiveMessage request will contain at least one of the available messages (if any) and up to the maximum number requested in the ReceiveMessage call.

http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-long-polling.html (emphasis added)

因此,SQS 找到并返回的“某物” 可能是所有消息(最多您的最大值),或消息的子集,因为如前所述,SQS 是一个分布式系统。可能会在“一旦我们找到某些东西后尽快返回”和“在整个系统中搜索所有可能的信息,直到客户端将接受的最大消息数”之间做出架构决策......并且,给定这些替代方案,大多数应用程序更喜欢“尽可能快地给我任何你能给我的东西”的更快响应似乎是合理的。

在从长轮询中返回空响应之前,您不知道自己实际上已经耗尽了队列。

关于java - Amazon SQS 长轮询不返回所有消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21099953/

相关文章:

java - 没有队列的 ThreadPoolExecutor

java - 检测全角和半角的空白 : regex VS Character. isWhitespace()

java - 排除mapstruct中的特定字段

amazon-web-services - AWS Interface Endpoint 每个 AZ 有超过 1 个子网?

amazon-web-services - 为什么我的 awsglue 作业仅使用一个执行程序和驱动程序?

amazon-web-services - 将存储桶文件复制到本地磁盘时出现问题

javascript - Javascript 中的异步方法队列

java - 代码约定规则放在哪里?

java - 什么是 NullPointerException,我该如何解决?

laravel-5 - 如何在指定队列运行 Laravel 作业