Leobreda.net

Web, .Net,
SQL, Cloud...

Produzindo e Consumindo mensagens com AWS SQS

Transfira tarefas exaustivas de um sistema crítico, para um processamento em segundo plano

O Amazon SQS é um serviço de mensageria (Message Queue, MQ), na qual permite desacoplar funcionalidades sistêmicas associadas a um alto consumo de recursos ou alto tempo de processamento, "terceirizando" assim tal tarefa a um processo em segundo plano.

Basicamente, o serviço pode utilizado em cenários onde não há a necessidade de uma resposta e substituído por uma "promessa" de que a informação será entregue ao destinatário. Seja daqui 1 segundo, em 1 minuto ou 1 hora.

Principais conceitos do AWS SQS

O AWS SQS não é o único serviço de MQ no mercado. Existem outras ferramentas que trazem a mesma funcionalidade (até mesmo superior), tais como Apache Kafka, ActiveMQ ou Kinesis.

Mensagem é a informação que uma aplicação A disponibiliza pra uma aplicação B. Pode ser um TXT, XML, JSON ou outro tipo de informação.

O SQS possui 2 interfaces:
Producer é a aplicação que produz a mensagem para o SQS. O envio de e-mail após o cadastro em um site, pode ser substituído pelo envio das informações ao SQS e com uma resposta de até 100ms.

Consumer é uma aplicação separada da solução principal (worker service), na qual consome as mensagens do SQS e realiza o envio do e-mail. Em outras palavras, é a aplicação que faz o trabalho pesado.

SQS não é apenas para envio de e-mail. Seja envio de SMS, LOGs sistêmicos a um repositório, enfim, qualquer envio de informação que não precisa devolver o resultado ao sistema principal.

O tamanho máximo de uma mensagem é de até 256kB. Parece pouco, mas corresponde a um texto em Lorem Ipsum com 348 parágrafos, 32.289 palavras. Na necessidade de transacionar mais informações, associe ao uso de S3.

O serviço é gratuito para até 1 milhão de mensagens por mês, mesmo após o tempo free tier. Existem cobranças nas mensagens ao sair com a informação da AWS.

Recomendações do AWS SQS

Infinitos producers pode se conectar numa única fila SQS. A recomendação é que somente 1 consumer faça a leitura da fila. Escalar consumers numa única fila acarretará num processamento duplo/triplo/N de uma mesma mensagem.

Modelos de utilização

PADRÃO quando o Consumer lê as mensagens no SQS, mas não na mesma ordem que as mesmas foram inseridas pelo Producer.

Este modelo é o mais rápido, e precisa utilizar com cautela onde exige uma orquestração dos dados, isto é, uma informação Z que depende de A, e o A ainda não foi processado.

FIFO (First In First Out) quando o Consumer lê as mensagens no SQS na mesma ordem que foram produzidas pelo Producer.

Este modelo é recomendado em cenários de orquestração, isto é, processa a informação A, B, C, ..., Z, onde Z depende da A, B, C.
Problema: quando uma informação não consegue ser processada onde o consumer não ter uma resiliência no tratamento de mensagens inválidas, ocorrerá o enfileiramento das demais mensagens, travando o processamento e requer uma ação humana para correção do problema.

Se você é plantonista e já atendeu este tipo de problema no meio da madrugada, vai perceber com o tempo que o FIFO não faz muito sentido em serviços de mensageria, e as vezes é melhor descartar 1 mensagem do que uma interrupção generalizada do serviço.

Criando uma fila SQS

No Console AWS, acesse Amazon SQS » Filas > Criar fila. Defina o modelo padrão e um nome para a fila.

Tempo limite de visibilidade: Tempo que uma mensagem fica "reservada" para um determinado consumer, quando há uma concorrência na leitura da fila.

Atraso de entrega: É o tempo que a mensagem pode chegar atrasada numa fila. Num cenário de consumer, essa mensagem só ficará disponível após esse atraso.

Tempo espera do recebimento da mensagem: Tempo que cada ciclo da sonda disponível no console aws ficará capturando novas mensagens.

Período da retenção da mensagem: é o tempo máximo que a mensagem fica armazenada no SQS, sendo excluída automaticamente após o período.

Tamanho máximo da mensagem: corresponde ao tamanho máximo de cada mensagem, 256kB.

Após a criação da fila, surgirá a URL, informação necessária para o desenvolvimento abaixo.

Preparando o ambiente

Caso você não tenha instalado o AWSCLI ou realizado um "aws configure", ...

  1. Abra o diretório %userprofile% e crie a pasta .aws
  2. Crie os arquivos config e credentials

access_key e secret_key são fornecidos em sua conta pessoal na AWS. Declare tais valores no arquivo credentials.

Este procedimento é necessário para que todas as aplicações executadas em seu computador, se conectem automaticamente as suas aplicações na AWS.

Bora codar

git clone https://github.com/leobreda/aws-sqs.git

Abra o ConsoleSQS.sln no Visual Studio

Na classe Program.cs, atualize a URL_SQL com a URL correspondente da fila.

private static string URL_SQS = "https://url-sqs-aqui";

Produzindo mensagens

Execute o aplicativo no Visual Studio. Escolha a opção 1 e aguarde o término do processamento.

Volte para o console AWS e vá até a opção Enviar e receber mensagens para surgir as mensagens produzidas pelo aplicativo.

Voltando ao aplicativo, selecione a opção 2 para criar uma mensagem próxima ao limite máximo (256kB). Volte ao console AWS e procure localizar a mensagem de aprox 240kB

Voltando ao aplicativo, selecione a opção 3 para LER e LIMPAR a fila. Volte ao console AWS e verá que a fila foi limpada.

Informações técnicas

Ler uma mensagem na fila não significa que a mensagem será excluída.
Para manter a mensagem na fila, comente o método DeleteMessageAsync.

client.DeleteMessageAsync(URL_SQS, msg.Messages[i].ReceiptHandle).Wait();

Cada conexão como consumer na fila tem um custo. Você pode ler até 10 mensagens por conexão. Mantenha esse número no máximo para reduzir a quantidade de leituras.

Você pode manter o método ReceiveMessageAsync conectado na fila, por até 20 segundos, "esperando" novas mensagens quando a fila estiver vazia. Tal comportamento é útil para reduzir conexões enquanto a fila estiver com baixo volume de mensagens não consumidas.

private static int MENSAGENS_LEITURA = 10;
private static int SEGUNDOS_QUEUE = 20;
...
return await sqsClient.ReceiveMessageAsync(new ReceiveMessageRequest
{
	QueueUrl = URL_SQS,
	MaxNumberOfMessages = MENSAGENS_LEITURA,
	WaitTimeSeconds = SEGUNDOS_QUEUE
});

Links úteis

Amazon Simple Queue Service Documentation: https://docs.aws.amazon.com/sqs/index.html

Managing large Amazon SQS messages using Amazon S3: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-s3-messages.html




Acessar todos os artigos »