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", ...
- Abra o diretório %userprofile% e crie a pasta .aws
- 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