我已设置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();
}
答案 0 :(得分:1)
问题不在接收消息中。那是在清理队列。根据清除队列文档(https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-purge-queue.html)
消息删除过程最多需要60秒。我们推荐 无论队列大小如何,都要等待60秒
在发送更新之前只需等待60秒即可解决此问题。