SQS从队列接收丢失的消息

时间:2019-10-12 14:50:52

标签: amazon-web-services amazon-sqs

我已设置AWS基础设施,以便对dynamo db条目的每次更新最终都在启用了重复数据删除的SQS FIFO队列中结束。我还有一个针对这种情况的测试,其中我清除了队列(该队列可以从诉讼中的其他测试中获取更新。为避免在接收正确的消息之前必须轮询大量消息,请在运行测试之前清除队列)并更新Dynamo Db,并在轮询队列时检查是否收到了这些条目。此测试不稳定,有时会失败,因为未从队列接收到我发送的所有更新。

队列只有一个使用者,这是我编写的测试。因此,就好像有另一个消费者在消费这些消息。

我通过AWS控制台检查了队列,该队列在测试结束时为空,并且由于设置了TIMEOUT值而在测试超时时不包含丢失的消息。

我在CDK中的队列配置

public Queue createSqsQueue() {
    return new Queue(this, "DynamoDbUpdateSqsQueue", QueueProps.builder()
            .withContentBasedDeduplication(true)
            .withFifo(true)
            .withQueueName("DynamoDbUpdateSqsQueue.fifo")
            .withReceiveMessageWaitTime(Duration.seconds(20))
            .build());
}

我的接收消息代码

private void assertExpectedDynamoDbUpdatesAreReceived() {
    List<String> expectedDynamoDbUpdates = getExpectedDynamoDbUpdates();
    List<String> actualDynamoDBUpdates = newArrayList();
    boolean allDynamoDbUpdatesReceived = false;
    stopWatch.start();
    while (!allDynamoDbUpdatesReceived && stopWatch.getTime() < TIMEOUT ) {
        List<String> receivedDynamoDbUpdates =
                AmazonSQSClientBuilder.standard().receiveMessage(queueUrl).getMessages().stream()
                        .map(this::processAndDelete)
                        .collect(Collectors.toList());
        actualDynamoDBUpdates.addAll(receivedDynamoDbUpdates);
        if(actualDynamoDBUpdates.containsAll(expectedDynamoDbUpdates)){
            allDynamoDbUpdatesReceived= true;
        }
    }
    stopWatch.stop();
    assert(allDynamoDbUpdatesReceived).isTrue();
}

1 个答案:

答案 0 :(得分:1)

问题不在接收消息中。那是在清理队列。根据清除队列文档(https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-purge-queue.html

  

消息删除过程最多需要60秒。我们推荐   无论队列大小如何,都要等待60秒

在发送更新之前只需等待60秒即可解决此问题。