Gerenciando filas do Amazon SQS em Java
1. Visão geral
Neste tutorial, vamos explorar comouse Amazon’s SQS (Simple Queue Service) using the Java SDK.
2. Pré-requisitos
As dependências do Maven, as configurações da conta da AWS e a conexão do cliente necessárias para usar o Amazon AWS SDK para SQS são as mesmas que emthis article here.
Assumindo que criamos uma instância deAWSCredentials, conforme descrito no artigo anterior, podemos prosseguir e criar nosso cliente SQS:
AmazonSQS sqs = AmazonSQSClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(Regions.US_EAST_1)
.build();
3. Criação de filas
Depois de configurar nosso cliente SQS,creating queues is fairly straightforward.
3.1. Criação de uma fila padrão
Vamos ver como podemos criar uma fila padrão. Para fazer isso,we’ll need to create an instance of CreateQueueRequest:
CreateQueueRequest createStandardQueueRequest = new CreateQueueRequest("example-queue");
String standardQueueUrl = sqs.createQueue(createStandardQueueRequest).getQueueUrl();
3.2. Criação de uma fila FIFO
Criar um FIFO é semelhante a criar uma fila padrão. Ainda usaremos uma instância deCreateQueueRequest, como fizemos anteriormente. Só desta vez,we’ll have to pass in queue attributes, and set the FifoQueue attribute to true:
Map queueAttributes = new HashMap<>();
queueAttributes.put("FifoQueue", "true");
queueAttributes.put("ContentBasedDeduplication", "true");
CreateQueueRequest createFifoQueueRequest = new CreateQueueRequest(
"example-queue.fifo").withAttributes(queueAttributes);
String fifoQueueUrl = sqs.createQueue(createFifoQueueRequest)
.getQueueUrl();
4. Postagem de mensagens em filas
Assim que tivermos nossas filas configuradas, podemos começar a enviar mensagens.
4.1. Postando uma mensagem em uma fila padrão
Para enviar mensagens para uma fila padrão, vamoshave to create an instance of SendMessageRequest.
Em seguida, anexamos um mapa de atributos de mensagem a esta solicitação:
Map messageAttributes = new HashMap<>();
messageAttributes.put("AttributeOne", new MessageAttributeValue()
.withStringValue("This is an attribute")
.withDataType("String"));
SendMessageRequest sendMessageStandardQueue = new SendMessageRequest()
.withQueueUrl(standardQueueUrl)
.withMessageBody("A simple message.")
.withDelaySeconds(30)
.withMessageAttributes(messageAttributes);
sqs.sendMessage(sendMessageStandardQueue);
OwithDelaySeconds() especifica após quanto tempo a mensagem deve chegar na fila.
4.2. Publicação de uma mensagem em uma fila FIFO
A única diferença, neste caso, é quewe’ll have to specify the group to which the message belongs:
SendMessageRequest sendMessageFifoQueue = new SendMessageRequest()
.withQueueUrl(fifoQueueUrl)
.withMessageBody("Another simple message.")
.withMessageGroupId("example-group-1")
.withMessageAttributes(messageAttributes);
Como você pode ver no exemplo de código acima, especificamos o grupo usandowithMessageGroupId().
4.3. Postagem de várias mensagens em uma fila
Também podemospost multiple messages to a queue, using a single request. Criaremos uma lista deSendMessageBatchRequestEntry que enviaremos usando uma instância deSendMessageBatchRequest:
List messageEntries = new ArrayList<>();
messageEntries.add(new SendMessageBatchRequestEntry()
.withId("id-1")
.withMessageBody("batch-1")
.withMessageGroupId("example-group-1"));
messageEntries.add(new SendMessageBatchRequestEntry()
.withId("id-2")
.withMessageBody("batch-2")
.withMessageGroupId("example-group-1"));
SendMessageBatchRequest sendMessageBatchRequest
= new SendMessageBatchRequest(fifoQueueUrl, messageEntries);
sqs.sendMessageBatch(sendMessageBatchRequest);
5. Lendo mensagens de filas
Podemos receber mensagens de nossas filas porinvoking the receiveMessage() method on an instance of ReceiveMessageRequest:
ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(fifoQueueUrl)
.withWaitTimeSeconds(10)
.withMaxNumberOfMessages(10);
List sqsMessages = sqs.receiveMessage(receiveMessageRequest).getMessages();
UsandowithMaxNumberOfMessages(),, especificamos quantas mensagens obter da fila - embora deva ser observado que o máximo é10.
O métodowithWaitTimeSeconds() ativalong-polling. Long polling é uma forma de limitar o número de solicitações de mensagens recebidas que enviamos para SQS.
Simplificando, isso significa que esperaremos até o número especificado de segundos para recuperar uma mensagem. Se não houver mensagens na fila durante esse período, a solicitação retornará vazia. Se uma mensagem chegar na fila durante esse período, ela será retornada.
Podemosget the attributes and body of a given message:
sqsMessages.get(0).getAttributes();
sqsMessages.get(0).getBody();
6. Exclusão de uma mensagem de uma fila
Para excluir uma mensagem, usaremos umDeleteMessageRequest:
sqs.deleteMessage(new DeleteMessageRequest()
.withQueueUrl(fifoQueueUrl)
.withReceiptHandle(sqsMessages.get(0).getReceiptHandle()));
7. Dead Letter Queues
A dead letter queue must be of the same type as its base queue — it deve ser FIFO se a fila base for FIFO, e padrão se a fila base for padrão. Para este exemplo, usaremos uma fila padrão.
A primeira coisa que precisamos fazer écreate what will become our dead letter queue:
String deadLetterQueueUrl = sqs.createQueue("example-dead-letter-queue").getQueueUrl();
Em seguida, vamosget our newly created queue’s ARN (Amazon Resource Name):
GetQueueAttributesResult deadLetterQueueAttributes = sqs.getQueueAttributes(
new GetQueueAttributesRequest(deadLetterQueueUrl)
.withAttributeNames("QueueArn"));
String deadLetterQueueARN = deadLetterQueueAttributes.getAttributes()
.get("QueueArn");
Finalmente, nósset this newly created queue to be our original standard queue’s dead letter queue:
SetQueueAttributesRequest queueAttributesRequest = new SetQueueAttributesRequest()
.withQueueUrl(standardQueueUrl)
.addAttributesEntry("RedrivePolicy",
"{\"maxReceiveCount\":\"2\", "
+ "\"deadLetterTargetArn\":\"" + deadLetterQueueARN + "\"}");
sqs.setQueueAttributes(queueAttributesRequest);
The JSON packet we set in the addAttributesEntry() method when building our SetQueueAttributesRequest instance contains the information we need: omaxReceiveCount é2, o que significa que se uma mensagem for recebida tantas vezes, presume-se que não foi processada corretamente e é enviada para nossa fila de mensagens não entregues.
O atributodeadLetterTargetArn aponta nossa fila padrão para a fila de devoluções recém-criada.
8. Monitoramento
Podemoscheck how many messages are currently in a given queue, and how many are in flight with the SDK. Primeiro, precisamos criar umGetQueueAttributesRequest.
A partir daí, verificaremos o estado da fila:
GetQueueAttributesRequest getQueueAttributesRequest
= new GetQueueAttributesRequest(standardQueueUrl)
.withAttributeNames("All");
GetQueueAttributesResult getQueueAttributesResult
= sqs.getQueueAttributes(getQueueAttributesRequest);
System.out.println(String.format("The number of messages on the queue: %s",
getQueueAttributesResult.getAttributes()
.get("ApproximateNumberOfMessages")));
System.out.println(String.format("The number of messages in flight: %s",
getQueueAttributesResult.getAttributes()
.get("ApproximateNumberOfMessagesNotVisible")));
Um monitoramento mais aprofundado pode ser alcançado usandoAmazon Cloud Watch.
9. Conclusão
Neste artigo, vimos comomanage SQS queues using the AWS Java SDK.
Como de costume, todos os exemplos de código usados no artigo podem ser encontradosover on GitHub.