Mensageria com Amazon SQS

São muitos os sistemas de mensageria disponíveis. Ou Message Oriented Middleware, MOM, se preferir.

Alguns exemplos que temos de MOM são: IBM MQSeries, RabbitMQ, HornetQ, ActiveMQ. Alguns servidores de aplicação tem internamente um MOM configurado, como o JBoss, que usa o hornetQ.

A amazon tem um MOM disponibilizado como serviço, dispensando a configuração e manutenção da infraestrutura, o SQS (Simple Queue Service).

Como funciona o SQS? Muito simples. Os desenvolvedores podem criar número ilimitado de filas e número ilimitado de mensagens e só vai ser cobrado pelo que for transferido para fora, porque os dados transferidos entre o SQS e uma máquina no EC2 dentro de uma mesma região são gratuitos.

Vamos usar o SDK da amazon para entender o funcionamento do SQS. Primeiro temos que configurar uma fila, como mostra a figura a seguir:

Nova Fila

A parametrização é tranquila, basta você dar um nome para a fila e definir algumas variáveis, como o período de visibilidade da mensagem e período de retenção da mensagem.

Então vamos ao código. Para publicar uma mensagem basta você instanciar o cliente e enviar a mensagem desejada. Lembrando que as credenciais que voçê tem que passar são as credenciais criadas na amazon para que uma aplicação a acesse de fora.

String url = "https://sqs.us-east-1.amazonaws.com/403828569551/caelum-queue-jms";
AmazonSQSClient sqsClient = new AmazonSQSClient(awsCredentials);
sqsClient.sendMessage(new SendMessageRequest()
                          .withQueueUrl(url).withMessageBody("Texto da MSG."));

Você pode visualizar a mensagem publicada utilizando o plugin da amazon pro eclipse. Veja a imagem a seguir:

Mensagem Enviada

Para receber a mensagem publicada basta criar um objeto do tipo ReceiveMessageRequest que aponta para a nossa fila na amazon instanciar nosso cliente e usar o método receiveMessage.

ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest("https://sqs.us-east-1.amazonaws.com/403828569551/caelum-queue-jms");
AmazonSQSClient sqsClient = new AmazonSQSClient(awsCredentials);
List<Message> messages = sqsClient.receiveMessage(receiveMessageRequest).getMessages();
for (Message message : messages) {
  System.out.println("MSG");
  System.out.println("MsgID:     " + message.getMessageId());
  System.out.println("Identificador Único MSG: " + message.getReceiptHandle());
  System.out.println("MD5 do Corpo da MSG:     " + message.getMD5OfBody());
  System.out.println("Corpo:          " + message.getBody());
  for (Entry<String, String> entry : message.getAttributes().entrySet()) {
    System.out.println("Atributos");
    System.out.println("Nome:  " + entry.getKey());
    System.out.println("Valor: " + entry.getValue());
  }
}

Para cada mensagem enviada o SQS gera um ID único para e um hash para você garantir que a mensagem não foi alterada e para poder ler a mensagem quantas vezes for necessário. Outro ponto interessante é que o SQS não faz FIFO (Fist in Fist out), ou seja, diferente dos outros sistemas de mensageria ele não remove automaticamente a mensagem já lida. Ela permanece lá até o tempo de validade dela expirar ou você executar a remoção de forma programática. Mas enquanto a mensagem está sendo lida ela fica bloqueada para que outros consumidores não leiam a mensagem igual. Se você precisa de FIFO, você tem que projetar sua aplicação para gerenciar isso.

É simples fazer essa remoção:

String url = "https://sqs.us-east-1.amazonaws.com/403828569551/caelum-queue-jms";
AmazonSQSClient sqsClient = new AmazonSQSClient(awsCredentials);
ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(url);
List<Message> messages = sqsClient.receiveMessage(receiveMessageRequest).getMessages();
System.out.println("Deletando a MSG.\n" + messages.get(0).getBody());
String messageReceiptHandle = messages.get(0).getReceiptHandle();
sqsClient.deleteMessage(new DeleteMessageRequest().withQueueUrl(url).withReceiptHandle(messageReceiptHandle));

Um outro serviço de mensageria que está se popularizando muito é o IronMQ ,que tem uma API REST, facilitando bastante o uso do serviço por aplicações web. O IronMQ também disponibiliza SDKs para diferentes linguagens. Vale a pena dar uma conferida.

Para aprender mais sobre o SDK da amazon e sobre o SQS, não deixe de ver o FAQ e a documentação, além desse nosso código de exemplo.

Tags: , , ,

6 Comentários

  1. Ruy Silva 16/10/2013 at 00:32 #

    Bem mais simples manter a infra fora!! Sem duvida uma boa solucao.

  2. Lucas Pérez 16/10/2013 at 09:31 #

    Excelente POST.

    Deixando simples o que tem que ser simples !!!! Essa é a ideia !!!!

    Parabéns pelo POST e realmente vale a pena dar uma olhada no IRON

  3. Leandro G Machado 17/10/2013 at 23:23 #

    Bom o post.
    De forma simples, tirou algumas dúvidas que tinha a respeito da implementação de Mensageria.

  4. Carlos Lima 20/10/2013 at 18:36 #

    ” porque os dados transferidos entre o SQS e uma máquina no EC2 dentro de uma mesma região são gratuitos.”

    Isso realmente me chamou atenção para estudar com minha empresa a implementação com a Amazon SQS.

    Obrigado pelas dicas instruções!

  5. José Henrique Honjoya 31/10/2013 at 08:26 #

    Ótima publicação, muito simples de entender o funcionamento do SQS. Parabéns

Deixe uma resposta