[英]AWS SQS Java. Not all messages are retrieved from the SQS queue
我一直在嘗試使用AWS SDK for Java從SQS隊列中檢索所有消息的幾種方法無濟於事。 我已經了解了AWS SQS的分布式特性,並且消息存儲在不同的服務器上。 但我不明白為什么這個架構不會被最終用戶隱藏。 我需要在Java代碼中應用哪些技巧來檢索所有消息,並且100%確定沒有人錯過?
我試着用“長輪詢” :
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();
這與請求批處理/客戶端緩沖:
// 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());
}
}
但我仍然無法檢索所有消息。
任何想法?
AWS論壇對我的帖子保持沉默。
從SQS隊列接收消息時,需要重復調用sqs:ReceiveMessage
。
在每次調用sqs:ReceiveMessage
,您將從隊列中獲得0個或更多消息,您需要迭代這些消息。 對於每條消息,您還需要調用sqs:DeleteMessage
,以便在處理sqs:DeleteMessage
消息后從隊列中刪除消息。
在上面的“長輪詢”示例周圍添加一個循環以接收所有消息。
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();
}
另請注意,您可能會多次收到相同的消息。 因此,允許您的工作“重新處理”相同的消息,或檢測重復的消息。
我也面臨同樣的問題 - 只有一條消息被返回,然后我嘗試了receiveMessageRequest.setMaxNumberOfMessages(10),這將幫助我在一個循環中檢索10條消息,
因為我的隊列有> 500條記錄,我所做的就是
List<String> messagelist = new ArrayList<>();
try
{
AmazonSQS sqs = new AmazonSQSClient(credentials);
Region usWest2 = Region.getRegion(Regions.US_WEST_2);
sqs.setRegion(usWest2);
boolean flag = true;
while(flag)
{
ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(queuename);
receiveMessageRequest.setMaxNumberOfMessages(number_of_message_);
receiveMessageRequest.withMaxNumberOfMessages(number_of_message_).withWaitTimeSeconds(wait_time_second_);
List<Message> messages = sqs.receiveMessage(receiveMessageRequest).getMessages();
for (Message message : messages)
{
// System.out.println(" Body: " + message.getBody());
messagelist.add( message.getBody());
String messageReceiptHandle = message.getReceiptHandle();
sqs.deleteMessage(new DeleteMessageRequest().withQueueUrl(queuename).withReceiptHandle(messageReceiptHandle));
}
if(messages.size()==0)
{
flag = false;
}
}
}
catch (AmazonServiceException ase) {
ase.printStackTrace();
} catch (AmazonClientException ace) {
ace.printStackTrace();
}
finally {
return messagelist ;
}
我正在從SQS讀取記錄,然后將其保存到String列表中,然后從隊列中刪除記錄。
所以最后我將列表中的隊列中的所有數據
如果隊列中沒有消息,則長輪詢將等待。 這意味着如果您使用循環中的長輪詢調用ReceiveMessage,則可以保證您將獲得所有消息。 當響應中收到0條消息時,您已收到所有消息。
您提到您還使用了Web控制台。 Web控制台的工作方式與使用SDK調用API的方式相同。 這意味着當您在控制台中接收和查看消息時,消息對其他客戶端是不可見的,直到可見性超時到期為止。 這可能是你沒有看到消息的原因。
查看有關可見性超時的更多信息
http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/AboutVT.html
SQS隊列不是數據庫。 您無法將所有消息讀入列表中,就像您嘗試做的那樣。 隊列沒有開始也沒有結束。 您輪詢隊列並詢問一些消息,它會返回一些消息(如果存在)。
如果你想要一個可以返回整個數據集的方法,那么sqs就不是正確的工具 - 在這種情況下,傳統的數據庫可能會更好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.