Tutorial de Node.js com filas na AWS SQS

Quando temos que lidar com um grande volume de requisições e/ou atividades, uma solução comum têm alguns anos é utilizar filas de mensagens e trabalhar com o conceito de processamento assíncrono. Já falei aqui no blog em outra oportunidade de como utilizar o RabbitMQ para isso, uma solução gratuita e popular para message queues.

No entanto, muitas vezes não queremos ter que fazer a gestão de uma solução de filas (recursos, segurança, monitoramento, etc), queremos apenas ter o poder delas em nossas mãos e aí que entram os provedores de serviços de fila em nuvem. Praticamente todos os cloud providers grandes possuem algo à sua disposição, cobrando apenas pelo uso.

Como o caso do AWS Simple Queue Service ou SQS, o “RabbitMQ”-as-a-Service fornecido pela Amazon, assunto do tutorial de hoje.

#1 – Setup da Fila

O primeiro passo obviamente é você ter uma conta na AWS, se autenticar no seu painel e ir na área de credenciais de segurança, que ficam dentro da sua conta de usuário (o menu com o seu nome no topo).

Uma vez dentro da área de credenciais de segurança, crie chaves de acesso (caso ainda não possua), lembrando que você pode ter até duas chaves apenas e que a Amazon não fornece backup, então guarde-as em um lugar seguro.

As chaves são compostas de um Access Key e de um Access Secret, sendo este último o mais “sensível” e que não deve ser compartilhado com ninguém. Usaremos estas informações mais tarde.

Agora vá no menu de Serviços na sua conta da AWS e procure por SQS, para acessar a tela de listagem de filas, como abaixo. Clique na opção Criar fila em laranja.

Abrirá uma tela de configuração da fila, onde inicialmente você tem de decidir se quer uma fila padrão ou uma FIFO (First In, First Out), sendo que a primeira possui maior performance, enquanto que a segunda garante a ordenação na entrega das mensagens conforme a ordem de chegada.

Na imagem abaixo, note que escolhi o tipo FIFO e com isso, sou obrigado a terminar o nome da minha fila com “.fifo”.

Avançando nas configurações da nossa fila, depois de lhe dar um nome, temos que pensar um pouco a respeito do seu comportamento. A documentação da Amazon é bem completa e ao lado de cada campo tem uma explicação do que ele impacta na fila.

Resumidamente temos:

  • Tempo limite de visibilidade: assim que um consumer/subscriber pega uma mensagem da fila, quanto tempo ele terá de “exclusividade” nesta mensagem antes dela estar disponível aos demais consumers/subscribers.
  • Atraso na entrega: suas mensagens serão imediatamente entregues aos consumers assim que chegarem na fila, ou você quer segurar um pouco?
  • Tempo de espera do recebimento da mensagem: você quer que as mensagens cheguem e sejam entregues uma a uma (maior custo e menor tempo) ou quer que sejam agrupadas em lotes de até 20 segundos de mensagens recebidas (menor custo e maior tempo)?
  • Período de retenção de mensagem: quantos dias uma mensagem pode ficar esperando para ser consumida na fila antes do SQS descartar ela?
  • Tamanho máximo da mensagem: quanto menor, melhor. Filas performam melhor com mensagens pequenas.
  • Desduplicação baseada em conteúdo: toda mensagem deve ser única. Se você marcar esta opção, o corpo inteiro da mensagem será considerado para desduplicação. Caso não marque, suas mensagens obrigatoriamente deverão ter um campo id.

O próximo passo são as configurações de segurança. Quem vai poder mandar e receber mensagens desta fila?

Escolhi o básico, permitindo que apenas o proprietário da fila (eu) consiga enviar e receber mensagens dela.

Clicando no botão de salvar, a fila será criada quase instantaneamente. Atenção à tela que se abrirá, de detalhes da fila, onde você precisa guardar as informações de URL e ARN.

Curso Node.js e MongoDB
Curso Node.js e MongoDB

#2 – Setup do Projeto

Crie um projeto Node.js e instale nele duas dependências, o AWS SDK e o dotenv.

O AWS SDK é a biblioteca de componentes prontos para usarmos os recursos da AWS em Node.js. Já o dotenv é um popular pacote para fazer gestão de variáveis de ambiente e configurações da sua aplicação.

Como o AWS SDK exige uma série de configurações de ambiente para funcionar adequadamente, usaremos o dotenv para fazer isto.

Agora, crie um arquivo criar arquivo .env na raiz do seu projeto, com o seguinte conteúdo.

Lembra das credenciais de acesso que criamos no início do tutorial? Pois é, precisaremos delas aqui, coloque o access key e o access secret neste arquivo, nos referidos campos.

O AWS_REGION você consegue bem fácil na sua conta, é só ver a região que está listada no topo da sua conta e usar a sigla dela na configuração do .env, será algo como us-east-1.

A URL da fila eu falei pra você pegar na tela de detalhes da fila recém criada, lembra? E o Message Group é uma exigência de filas FIFO. Se a sua for FIFO, coloque nesta configuração qualquer palavra que quiser, já se não for FIFO, você não pode ter esta configuração.

#3 – Enviando mensagens

Agora que temos a infraestrutura e o projeto criados e configurados, é hora de construirmos o código que enviará mensagens para a fila.

Crie um arquivo sqsClient.js na raiz do seu projeto e inclua o código abaixo dentro dele, que cometarei a seguir.

A primeira linha é apenas um require para carregar o AWS SDK que instalamos antes. A função sendMessage espera a mensagem a ser enfileirada e no seu interior executa os seguintes passos:

  1. configura a região da AWS onde está nossa fila;
  2. instancia um objeto SQS usando uma classe do AWS SDK específica pro SQS;
  3. executa e retorna função sendMessage do SQS, que espera um corpo da mensagem, a URL da mesma e o messageGroup, todos parâmetros do tipo string.

Note que chamei uma função .promise() ao fim do sendMessage. Isso porque, por padrão, o sendMessage espera um callback e se quisermos trabalhar com Promises, precisamos desta última chamada que adicionei.

Após exportar nossa função no sqsClient.js, vamos voltar à raiz do projeto e criar nosso producer.js, o arquivo que vai usar o client para enviar mensagens pro SQS.

Aqui, importo e configuro o dotenv como primeira linha, para que as variáveis de ambiente sejam carregadas antes de tudo.

Depois, importo o sqsClient e utilizo ele para enviar uma mensagem utilizando o formato JSON. Utilizei de Async/Await para que a legibilidade fique mais simples, mas isso exige que todo o meu escopo esteja dentro de uma função assíncrona, o que fiz com um IIFE.

Se der algum erro, o bloco try/catch vai desviar o fluxo de execução e jogar no console para entendermos o que aconteceu.

Para testar essa aplicação de producer, execute este arquivo no console.

Se tudo deu certo, você deve conseguir ir na seção de Monitoramento na sua fila SQS e em poucos segundos deve aparecer lá que a sua fila possui mensagens ainda não processadas. Na verdade o envio da mensagem para a fila é quase instantâneo, esses segundos é para aparecer no monitoramento mesmo.

E aí, gostou do tutorial? Quer uma segunda parte, ensinando como fazer o recebimento de mensagens por um consumer/subscriber?

Que tal o consumer não ser um módulo JS simples, mas sim uma função serverless/Lambda na AWS?

Deixa aí nos comentários!

Quer ver na prática como utilizar a fila da AWS em um projeto de software real, usando a stack completa do JavaScript? Conheça meu curso clicando no banner abaixo!

Curso FullStack
Curso FullStack

Publicado por

Luiz Duarte

Pós-graduado em computação, professor, empreendedor, autor, Agile Coach e programador nas horas vagas.