AWS SQS Java. Not all messages are retrieved from the SQS queue
I've been trying to use AWS SDK for Java to retrieve all messages from the SQS queue I have learned about the distributed nature of AWS SQS, and messages are stored on different servers But I don't understand why this architecture won't be hidden by end users What skills do I need to apply in Java code to retrieve all messages and be 100% sure no one misses?
I try to use "long polling":
ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(myQueueUrl); List<Message> messages = sqs.receiveMessage(receiveMessageRequest).getMessages(); for (Message message : messages) { System.out.println(" Message"); System.out.println(" MessageId: " + message.getMessageId()); System.out.println(" ReceiptHandle: " + message.getReceiptHandle()); System.out.println(" MD5OfBody: " + message.getMD5OfBody()); System.out.println(" Body: " + message.getBody()); for (Entry<String,String> entry : message.getAttributes().entrySet()) { System.out.println(" Attribute"); System.out.println(" Name: " + entry.getKey()); System.out.println(" Value: " + entry.getValue()); } } System.out.println();
This is similar to request batching / client buffering:
// Create the basic Amazon SQS async client AmazonSQSAsync sqsAsync = new AmazonSQSAsyncClient(); // Create the buffered client AmazonSQSAsync bufferedSqs = new AmazonSQSBufferedAsyncClient(sqsAsync); CreateQueueRequest createRequest = new CreateQueueRequest().withQueueName("MyTestQueue"); CreateQueueResult res = bufferedSqs.createQueue(createRequest); SendMessageRequest request = new SendMessageRequest(); String body = "test message_" + System.currentTimeMillis(); request.setMessageBody( body ); request.setQueueUrl(res.getQueueUrl()); SendMessageResult sendResult = bufferedSqs.sendMessage(request); ReceiveMessageRequest receiveRq = new ReceiveMessageRequest() .withMaxNumberOfMessages(10) .withQueueUrl(queueUrl); ReceiveMessageResult rx = bufferedSqs.receiveMessage(receiveRq); List<Message> messages = rx.getMessages(); for (Message message : messages) { System.out.println(" Message"); System.out.println(" MessageId: " + message.getMessageId()); System.out.println(" ReceiptHandle: " + message.getReceiptHandle()); System.out.println(" MD5OfBody: " + message.getMD5OfBody()); System.out.println(" Body: " + message.getBody()); for (Entry<String,String> entry : message.getAttributes().entrySet()) { System.out.println(" Attribute"); System.out.println(" Name: " + entry.getKey()); System.out.println(" Value: " + entry.getValue()); } }
But I still can't retrieve all the messages
Any ideas?
AWS forum kept silent on my post
Solution
When receiving a message from the SQS queue, you need to call SQS: receivemessage repeatedly
Every time you call SQS: receivemessage, you will get 0 or more messages from the queue. You need to iterate over these messages For each message, you also need to call SQS: deletemessage to delete the message from the queue after processing each message
Add a loop around the "long polling" example above to receive all messages
for (;;) { ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(myQueueUrl); List<Message> messages = sqs.receiveMessage(receiveMessageRequest).getMessages(); for (Message message : messages) { System.out.println(" Message"); System.out.println(" MessageId: " + message.getMessageId()); System.out.println(" ReceiptHandle: " + message.getReceiptHandle()); System.out.println(" MD5OfBody: " + message.getMD5OfBody()); System.out.println(" Body: " + message.getBody()); for (Entry<String,String> entry : message.getAttributes().entrySet()) { System.out.println(" Attribute"); System.out.println(" Name: " + entry.getKey()); System.out.println(" Value: " + entry.getValue()); } } System.out.println(); }
Also note that you may receive the same message multiple times Therefore, allow your work to "reprocess" the same message or detect duplicate messages